Compare commits
794 Commits
1.32.0-245
...
v3.3.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e955da14fa | ||
|
|
52eeccaba1 | ||
|
|
3a1e3bc596 | ||
|
|
e0dbd8f74a | ||
|
|
6a25b3bfa0 | ||
|
|
aee2599904 | ||
|
|
d56381666a | ||
|
|
611cde7202 | ||
|
|
181bad9563 | ||
|
|
73b2ff0945 | ||
|
|
89c5a4dfea | ||
|
|
d4b3d21dce | ||
|
|
40778b15ca | ||
|
|
d7234029e6 | ||
|
|
10b06cae10 | ||
|
|
0bd2602774 | ||
|
|
c69346a9a7 | ||
|
|
5651201643 | ||
|
|
f475767c2b | ||
|
|
a0a77e379e | ||
|
|
f4a78587b0 | ||
|
|
b3ae4d67d3 | ||
|
|
d30f3dbdf7 | ||
|
|
1739b21600 | ||
|
|
a346c6d565 | ||
|
|
502c262c82 | ||
|
|
4aae5eaeca | ||
|
|
41d625abb6 | ||
|
|
8626bed4ef | ||
|
|
dc632ac176 | ||
|
|
c0d6eb4664 | ||
|
|
524b0205e9 | ||
|
|
1e432b25ea | ||
|
|
d6ea9d78f6 | ||
|
|
28edf4af2e | ||
|
|
d288131a33 | ||
|
|
e02d94ad2f | ||
|
|
4f67f4e096 | ||
|
|
00d164b67f | ||
|
|
c5179c2a06 | ||
|
|
95ac0ddfb7 | ||
|
|
2e31e8f0c9 | ||
|
|
169f8c67fe | ||
|
|
b706e85efb | ||
|
|
7c7f62d3f3 | ||
|
|
231e31656a | ||
|
|
4590c3a3db | ||
|
|
e9fe4c0466 | ||
|
|
6282cd7e7b | ||
|
|
bc453b5f0d | ||
|
|
0ec1c69c06 | ||
|
|
193a45113c | ||
|
|
3e7582880e | ||
|
|
c63f1ea62a | ||
|
|
1a375a44e0 | ||
|
|
be032cf735 | ||
|
|
4875f6aa87 | ||
|
|
0a2f06b296 | ||
|
|
6a2662eeee | ||
|
|
a64f80d2d4 | ||
|
|
1898dea314 | ||
|
|
81411b2af9 | ||
|
|
c4b620d69e | ||
|
|
c04befac68 | ||
|
|
fd36a99a4c | ||
|
|
4b09746c37 | ||
|
|
870cf4f3fe | ||
|
|
1ff35f177d | ||
|
|
f3edb1cc5f | ||
|
|
86dc38e69f | ||
|
|
a2b69c8f3f | ||
|
|
4cfd7c50ad | ||
|
|
a96606e589 | ||
|
|
30aefe19b5 | ||
|
|
37184f456c | ||
|
|
05456024c4 | ||
|
|
5accf3fe5f | ||
|
|
2dd27b4cb8 | ||
|
|
af28885ea6 | ||
|
|
f21ba53609 | ||
|
|
181e0ea6c8 | ||
|
|
6074ca275b | ||
|
|
d0d5461a67 | ||
|
|
8608ae2f08 | ||
|
|
401f08db63 | ||
|
|
caa299b60d | ||
|
|
dcde596002 | ||
|
|
ee14db20f1 | ||
|
|
27ba64c7e4 | ||
|
|
c7753f2cf9 | ||
|
|
974d4cb8fc | ||
|
|
29b6115c77 | ||
|
|
28e91ba70c | ||
|
|
5aded14b87 | ||
|
|
a288351ad4 | ||
|
|
3b39482420 | ||
|
|
a5c35af81b | ||
|
|
b78bdaf46e | ||
|
|
aefef5b0e8 | ||
|
|
ca998240a0 | ||
|
|
d2a31477c7 | ||
|
|
9c6581273e | ||
|
|
d1445a8135 | ||
|
|
5fc00acc39 | ||
|
|
363cdd02df | ||
|
|
a5d1d3b90e | ||
|
|
aaa6c279a1 | ||
|
|
498becd11f | ||
|
|
411c61fb02 | ||
|
|
74a0bacdcf | ||
|
|
e7e7b0ffb7 | ||
|
|
fd339a7433 | ||
|
|
561b6343c8 | ||
|
|
e68d72c4d6 | ||
|
|
737a8f5965 | ||
|
|
c0dd29c591 | ||
|
|
8aa5675ba2 | ||
|
|
2086648c87 | ||
|
|
3a98d856a5 | ||
|
|
90fd1f7dd1 | ||
|
|
77ad73d579 | ||
|
|
13534fa0c0 | ||
|
|
37299abcc9 | ||
|
|
e480f6527e | ||
|
|
26584f2060 | ||
|
|
a4c0fd1fdc | ||
|
|
6c104c016e | ||
|
|
599670136d | ||
|
|
ce637d318d | ||
|
|
d8654b5a19 | ||
|
|
12c3ccd6c7 | ||
|
|
7954656610 | ||
|
|
87ebf03eb7 | ||
|
|
df1c34e291 | ||
|
|
4a65b58772 | ||
|
|
11fdb8854b | ||
|
|
0a92bb1607 | ||
|
|
5bac2cbdb8 | ||
|
|
511c3e95b2 | ||
|
|
0a5687bacf | ||
|
|
27320465b7 | ||
|
|
6df454e006 | ||
|
|
216652fb31 | ||
|
|
0f066d30b4 | ||
|
|
d1687c1533 | ||
|
|
f5f29c0120 | ||
|
|
8a6faa39c9 | ||
|
|
5887c1d339 | ||
|
|
664ef17af8 | ||
|
|
004004c047 | ||
|
|
09db0ffad5 | ||
|
|
a349ea8ff9 | ||
|
|
cfebf2c67f | ||
|
|
ddd44999c6 | ||
|
|
89d78a5921 | ||
|
|
99dd2db97c | ||
|
|
b52fbb4cb9 | ||
|
|
3463d56114 | ||
|
|
5f63d2b822 | ||
|
|
db4a4f0f50 | ||
|
|
d192726e80 | ||
|
|
d832f61d5b | ||
|
|
88f4b986c5 | ||
|
|
aeb6261189 | ||
|
|
6cb228037b | ||
|
|
a00fa85d77 | ||
|
|
57de78e12a | ||
|
|
2342443368 | ||
|
|
26647c54c9 | ||
|
|
253cf1c438 | ||
|
|
f6a5eaa965 | ||
|
|
f83a57a010 | ||
|
|
92cec80b0e | ||
|
|
1f601f27a2 | ||
|
|
71f1291623 | ||
|
|
9b07078b47 | ||
|
|
8433a3d081 | ||
|
|
c8269fb54d | ||
|
|
0b9a478289 | ||
|
|
c7e6e58387 | ||
|
|
8c515029fd | ||
|
|
1f6ff2f763 | ||
|
|
04542c99fd | ||
|
|
8c47ba255a | ||
|
|
4e6f6bc2cc | ||
|
|
7c65a54fcf | ||
|
|
1f43a673df | ||
|
|
744327ffd4 | ||
|
|
a442d3e3f9 | ||
|
|
3e8a6f93a4 | ||
|
|
308a84e6ec | ||
|
|
cc139acfd1 | ||
|
|
32f8f481b6 | ||
|
|
ec55ed39ee | ||
|
|
ee4b939efa | ||
|
|
538e8d8085 | ||
|
|
2c4ca14d53 | ||
|
|
8d934be6dc | ||
|
|
c54450941c | ||
|
|
e0e019fbd5 | ||
|
|
77af2a5b0e | ||
|
|
ecac0dd751 | ||
|
|
79b4c64a03 | ||
|
|
ccd01c49b9 | ||
|
|
069c5230cd | ||
|
|
c146457de4 | ||
|
|
88cab27165 | ||
|
|
a8914b025f | ||
|
|
0f87798ed6 | ||
|
|
963ebaca5b | ||
|
|
eef2ed0e78 | ||
|
|
0e3720169f | ||
|
|
21cfeb9da0 | ||
|
|
fd65cadaea | ||
|
|
70ad2354bb | ||
|
|
01710cf6ff | ||
|
|
b5c425b3a6 | ||
|
|
b00f6bf078 | ||
|
|
a2639ac617 | ||
|
|
07fcf1be7a | ||
|
|
75ca5b2b0b | ||
|
|
082f25faf1 | ||
|
|
595ce6f5e3 | ||
|
|
b1760c8d29 | ||
|
|
c870398c86 | ||
|
|
f76c809f7d | ||
|
|
4c6e4bedeb | ||
|
|
04e449c546 | ||
|
|
c147711ade | ||
|
|
bd7583a254 | ||
|
|
33b3523bf4 | ||
|
|
cf0f11105b | ||
|
|
9b7a203fe5 | ||
|
|
e44ac0a30e | ||
|
|
319cd3f7ab | ||
|
|
815dc06118 | ||
|
|
3a2644a2bc | ||
|
|
65690fca65 | ||
|
|
25288b1afd | ||
|
|
288e794c99 | ||
|
|
c567a06ff5 | ||
|
|
e5b68a8f4c | ||
|
|
51a5c77cb8 | ||
|
|
b9e7a3daa7 | ||
|
|
80b2d9481f | ||
|
|
0e2eaa9b34 | ||
|
|
0263188431 | ||
|
|
fa30639784 | ||
|
|
015b8dcf13 | ||
|
|
9f3240346c | ||
|
|
b76364db31 | ||
|
|
a065c12e83 | ||
|
|
76831f11fc | ||
|
|
b6aa0cbcba | ||
|
|
5681c87e33 | ||
|
|
46d6e17508 | ||
|
|
1aaa53622d | ||
|
|
bdb189a9bb | ||
|
|
8793110941 | ||
|
|
16bcf59cb0 | ||
|
|
f6b092b12d | ||
|
|
d47591e253 | ||
|
|
1a91588c42 | ||
|
|
39a57700bc | ||
|
|
1a54f6b7ef | ||
|
|
eb3cf303ad | ||
|
|
0d31a51eeb | ||
|
|
61d1af0413 | ||
|
|
4aa15401c3 | ||
|
|
80b1b1b672 | ||
|
|
0ec83f8736 | ||
|
|
db54f78e8e | ||
|
|
b8fa7da972 | ||
|
|
bf1be16d11 | ||
|
|
cc79edb312 | ||
|
|
ac4f2b8215 | ||
|
|
c8fc54bfb1 | ||
|
|
d574012871 | ||
|
|
250a54220c | ||
|
|
5baf16622f | ||
|
|
256419004d | ||
|
|
6a693e7181 | ||
|
|
b38cfa473e | ||
|
|
26f8216ec8 | ||
|
|
63f3c04c57 | ||
|
|
8a0f1d846e | ||
|
|
efaeb3b110 | ||
|
|
6cebfa469d | ||
|
|
205775ac97 | ||
|
|
4cc181cedc | ||
|
|
a149c5fc60 | ||
|
|
6e809b6a31 | ||
|
|
7c6fe56043 | ||
|
|
8cc11d1688 | ||
|
|
dbc5c065f8 | ||
|
|
4a54e914fc | ||
|
|
b30aefcfb1 | ||
|
|
b29346ecdf | ||
|
|
ef8da3864f | ||
|
|
108eb297d8 | ||
|
|
19f3acd9f0 | ||
|
|
3ee6b0ff0b | ||
|
|
e270f7da1b | ||
|
|
e6117decd0 | ||
|
|
c7127cb248 | ||
|
|
50234e5f04 | ||
|
|
5f562dc113 | ||
|
|
bb8bad49dc | ||
|
|
a674d882bf | ||
|
|
f51e045cd5 | ||
|
|
8122b7f69e | ||
|
|
25f18beda4 | ||
|
|
7e7923706f | ||
|
|
ae35673489 | ||
|
|
23f142fdc6 | ||
|
|
101139fabf | ||
|
|
e2d354c8f2 | ||
|
|
7c178805ea | ||
|
|
45f70e741f | ||
|
|
1474a82c7d | ||
|
|
d97feca3ba | ||
|
|
b2669e78bf | ||
|
|
66ee6e8201 | ||
|
|
62f050fda7 | ||
|
|
57425377e5 | ||
|
|
174cb2f8a9 | ||
|
|
42bddce21f | ||
|
|
f2a15795a1 | ||
|
|
6dd5e515c5 | ||
|
|
92da02ef3e | ||
|
|
3ce7129492 | ||
|
|
336ee28888 | ||
|
|
3f2240ab65 | ||
|
|
1087037728 | ||
|
|
1959d82912 | ||
|
|
8024144381 | ||
|
|
6a1dcab7a6 | ||
|
|
e6d1f2a7c8 | ||
|
|
44c4722edf | ||
|
|
e5fc63f2c8 | ||
|
|
015a99e87d | ||
|
|
884491d72b | ||
|
|
e14362f322 | ||
|
|
917aa48072 | ||
|
|
938c6ef829 | ||
|
|
0add01d383 | ||
|
|
2018024810 | ||
|
|
a1d6bcb8e5 | ||
|
|
727ac6483b | ||
|
|
2c15c09fc0 | ||
|
|
2ad2582cc0 | ||
|
|
cee0ac213c | ||
|
|
780a673017 | ||
|
|
af71203955 | ||
|
|
fc3acfabb2 | ||
|
|
3d5db8313a | ||
|
|
73cf8f34e3 | ||
|
|
766efd6079 | ||
|
|
87485948ad | ||
|
|
7e4a73ce2d | ||
|
|
2f0878d9b7 | ||
|
|
f65c9b23fc | ||
|
|
cd859d117f | ||
|
|
e22964915a | ||
|
|
197d0b6ca9 | ||
|
|
422503ef98 | ||
|
|
ea36345d2c | ||
|
|
a89d83cbba | ||
|
|
83ff31b620 | ||
|
|
3a9b032c72 | ||
|
|
f73e9225b4 | ||
|
|
168ccb0dfc | ||
|
|
58f7f5b769 | ||
|
|
b8e6369fbe | ||
|
|
d81d5f499f | ||
|
|
4be178d234 | ||
|
|
9c40466b4b | ||
|
|
95693fb58e | ||
|
|
e7945bea94 | ||
|
|
91f49e1efd | ||
|
|
eea9c1618c | ||
|
|
f1b38e4e48 | ||
|
|
ff99a1d768 | ||
|
|
7f07b8f66c | ||
|
|
faae03da6b | ||
|
|
a6e4f96737 | ||
|
|
cc7585bbc2 | ||
|
|
14a0cd3ffd | ||
|
|
3ff83eda45 | ||
|
|
f133b00851 | ||
|
|
ece840834d | ||
|
|
76f6ff4145 | ||
|
|
2458cde498 | ||
|
|
82e2b8a169 | ||
|
|
5aa2abaf9f | ||
|
|
fdb2308c62 | ||
|
|
4cd2f2cd52 | ||
|
|
88cef85f62 | ||
|
|
bdd11f741b | ||
|
|
56ce780522 | ||
|
|
567010e163 | ||
|
|
4ae2c81157 | ||
|
|
ae43e2016f | ||
|
|
3f6cbfa4dd | ||
|
|
1c50b5285e | ||
|
|
ea9c511db8 | ||
|
|
e1e3f32643 | ||
|
|
4290cffe3b | ||
|
|
548d095611 | ||
|
|
846dcbb947 | ||
|
|
d7d3368cc2 | ||
|
|
134040fea3 | ||
|
|
65caa26d40 | ||
|
|
7812f6b75a | ||
|
|
637e58f255 | ||
|
|
6135630fc0 | ||
|
|
22058c5f86 | ||
|
|
616bdb35f3 | ||
|
|
42f7b5d12b | ||
|
|
53818b0e36 | ||
|
|
6f08b13540 | ||
|
|
d36526b1c8 | ||
|
|
1252eb6a8a | ||
|
|
4733c31a2f | ||
|
|
17c5173d8b | ||
|
|
d0a08f6dd7 | ||
|
|
7b5d6d186b | ||
|
|
3851927396 | ||
|
|
7eececead6 | ||
|
|
b8c3d96fcd | ||
|
|
a2ee6c8e73 | ||
|
|
ef069d9b0e | ||
|
|
6a864f9f47 | ||
|
|
5c16399810 | ||
|
|
0141ded35d | ||
|
|
bb46e80d44 | ||
|
|
1bd5eca73d | ||
|
|
48a97abe1d | ||
|
|
0ff8a11c7f | ||
|
|
8b1cdaa4a1 | ||
|
|
0bbaa9763b | ||
|
|
dbe5f23e21 | ||
|
|
7353be413c | ||
|
|
398bc2ff41 | ||
|
|
ae1126d43f | ||
|
|
46d16811b9 | ||
|
|
f8635a124f | ||
|
|
c3c50e9a6a | ||
|
|
cb0f9c58d2 | ||
|
|
8643bdc9d7 | ||
|
|
5b51999df7 | ||
|
|
64cc2895f3 | ||
|
|
51a82655a9 | ||
|
|
0e1fed3c24 | ||
|
|
e9fce801a0 | ||
|
|
1164801376 | ||
|
|
12e608468b | ||
|
|
ed3e9d31f4 | ||
|
|
44000459da | ||
|
|
9d8906d250 | ||
|
|
a26844ea45 | ||
|
|
da7d8b04a8 | ||
|
|
12bc26b6b4 | ||
|
|
976a326f47 | ||
|
|
b901043bfc | ||
|
|
624a4c08b9 | ||
|
|
c9ce9ebb2e | ||
|
|
a3ee7c96a0 | ||
|
|
d33b2d2af9 | ||
|
|
830ccfe245 | ||
|
|
78b6b3afdf | ||
|
|
c4fd725875 | ||
|
|
4800ec6392 | ||
|
|
3e2d12a224 | ||
|
|
ddd5a9ae79 | ||
|
|
950dad9489 | ||
|
|
c19223b7fe | ||
|
|
80050d0d9d | ||
|
|
c2be0ec71b | ||
|
|
ccc4f87ada | ||
|
|
534600c1ff | ||
|
|
0f1bbc3161 | ||
|
|
615948c73f | ||
|
|
b9fc40409a | ||
|
|
e53d6bce68 | ||
|
|
ce3b7dfb1e | ||
|
|
19541c27ff | ||
|
|
c94761f312 | ||
|
|
b4e1a62cb4 | ||
|
|
7caef7f49c | ||
|
|
6737384d27 | ||
|
|
f61a0ae78a | ||
|
|
d1662d7658 | ||
|
|
72fe124e30 | ||
|
|
a48c2fb119 | ||
|
|
07ec4ca63e | ||
|
|
83f86a45b6 | ||
|
|
45ad7f020a | ||
|
|
2470081789 | ||
|
|
c11d5fe9e6 | ||
|
|
90e8714e71 | ||
|
|
5539519691 | ||
|
|
b566b66590 | ||
|
|
7389d9e2cb | ||
|
|
1d61cbe536 | ||
|
|
2807ce495e | ||
|
|
ba7285192c | ||
|
|
8c39e085f4 | ||
|
|
b257c60636 | ||
|
|
6b579d65ef | ||
|
|
d4ed2efa71 | ||
|
|
3667b16cba | ||
|
|
2b3e8e1a89 | ||
|
|
f5a6f14ade | ||
|
|
01a9ab332e | ||
|
|
9d688e0894 | ||
|
|
7d35144952 | ||
|
|
7e794bd134 | ||
|
|
dc333d4321 | ||
|
|
590f699687 | ||
|
|
dde683d911 | ||
|
|
950bfce420 | ||
|
|
5b64cb3400 | ||
|
|
712274d912 | ||
|
|
bdd9d65146 | ||
|
|
60ed0653bc | ||
|
|
bce0cac48f | ||
|
|
bd0f1d024b | ||
|
|
5944b842de | ||
|
|
12af311ce7 | ||
|
|
62719ab544 | ||
|
|
0315b004a7 | ||
|
|
87be3ac235 | ||
|
|
011530e11b | ||
|
|
4bfa686433 | ||
|
|
c67844d356 | ||
|
|
8ded89e8d4 | ||
|
|
4c4a179bce | ||
|
|
a4f21fb0d4 | ||
|
|
329acbb251 | ||
|
|
fd55139c82 | ||
|
|
7b7f5b542e | ||
|
|
92daabc75c | ||
|
|
068e07bd5d | ||
|
|
436ef7bd5c | ||
|
|
09cd1e8540 | ||
|
|
cd54aec2f9 | ||
|
|
078af59fd8 | ||
|
|
36b8731cfe | ||
|
|
9fdfacb314 | ||
|
|
e8cb6ffaa0 | ||
|
|
2be452d83e | ||
|
|
b0e6c1cc4e | ||
|
|
45d348b03d | ||
|
|
4b0cceb91a | ||
|
|
db41f106bc | ||
|
|
b6fdb7d0e7 | ||
|
|
1a3fc86894 | ||
|
|
83819cb3f9 | ||
|
|
feabfc86fa | ||
|
|
9b0b337dc0 | ||
|
|
9446cc8245 | ||
|
|
68c62087dc | ||
|
|
8dcc1e3567 | ||
|
|
e22791ec88 | ||
|
|
286f9a8978 | ||
|
|
97167e75ff | ||
|
|
2b2aa9a211 | ||
|
|
81862d4fa1 | ||
|
|
2fdf09e6e7 | ||
|
|
09e3cfd881 | ||
|
|
54ffd1d351 | ||
|
|
86e8ba12e7 | ||
|
|
f482087475 | ||
|
|
fe1d609d1a | ||
|
|
a20fa4a97a | ||
|
|
f51751ad21 | ||
|
|
197d8dba93 | ||
|
|
3ca90a5f89 | ||
|
|
6156eb9ff4 | ||
|
|
f8f4bfd76f | ||
|
|
5677ff2edf | ||
|
|
61c281ec6b | ||
|
|
770e0db7b8 | ||
|
|
6a35ab1dc0 | ||
|
|
3a78c0964f | ||
|
|
4685f6793d | ||
|
|
2e77c9d449 | ||
|
|
a6703ecb98 | ||
|
|
57a8186e88 | ||
|
|
d808bfaec6 | ||
|
|
7072bf1e83 | ||
|
|
4e0a6d2941 | ||
|
|
0d618bb1ef | ||
|
|
a0121f2f0c | ||
|
|
98f001395c | ||
|
|
68fe085aa3 | ||
|
|
4861405683 | ||
|
|
310bfe509e | ||
|
|
f25a614333 | ||
|
|
0ae8c1820a | ||
|
|
e776f18192 | ||
|
|
72d71664b3 | ||
|
|
1046fc192e | ||
|
|
c48a275d33 | ||
|
|
79e08c74ed | ||
|
|
3f2ad7b719 | ||
|
|
5e8c3f8ff3 | ||
|
|
ddab1a0626 | ||
|
|
d950e3c9de | ||
|
|
46298c7675 | ||
|
|
14d917179c | ||
|
|
a65773338c | ||
|
|
9b5a43e4bd | ||
|
|
46207cfe10 | ||
|
|
242bb6ffa2 | ||
|
|
e6713db677 | ||
|
|
11784e55b2 | ||
|
|
a72e8a698d | ||
|
|
28c93612e6 | ||
|
|
a9d17882e7 | ||
|
|
cf63bbd003 | ||
|
|
02f62882b8 | ||
|
|
362715bbeb | ||
|
|
ec70ea6994 | ||
|
|
04adf14146 | ||
|
|
406ec0ba71 | ||
|
|
e2eaa0aa4e | ||
|
|
a2ad3d4ff4 | ||
|
|
4a29cd1664 | ||
|
|
0462a93f11 | ||
|
|
db39eacfa1 | ||
|
|
91bcbe496b | ||
|
|
c020cd2f2c | ||
|
|
81bbfa7fbe | ||
|
|
aa1474b675 | ||
|
|
8256252967 | ||
|
|
07342bbee7 | ||
|
|
72152f74ab | ||
|
|
420ca76f54 | ||
|
|
31503fc853 | ||
|
|
cf399ef6ac | ||
|
|
bb5836ec61 | ||
|
|
f36235e03f | ||
|
|
6ef1628acb | ||
|
|
ab8f8a0a22 | ||
|
|
cdb900aca8 | ||
|
|
1622fd4152 | ||
|
|
6c972e855f | ||
|
|
e332882a88 | ||
|
|
d0142e2536 | ||
|
|
e8c8fba91d | ||
|
|
01a63a7241 | ||
|
|
a2e0638c6a | ||
|
|
4e62f938a9 | ||
|
|
4c5bb83fc1 | ||
|
|
a3ac4567e3 | ||
|
|
58cf109a83 | ||
|
|
fab45dedcd | ||
|
|
446573809c | ||
|
|
5ad9398b01 | ||
|
|
bcdbd90197 | ||
|
|
0de7247868 | ||
|
|
c9f91e77cd | ||
|
|
30b8565e2d | ||
|
|
6b887dcc9c | ||
|
|
41c7d98b7b | ||
|
|
b055a26dc3 | ||
|
|
2bc6e1a457 | ||
|
|
e61ea796c6 | ||
|
|
d073622629 | ||
|
|
5f40ebb845 | ||
|
|
c56e2797cc | ||
|
|
166efcb17e | ||
|
|
206e107a9a | ||
|
|
12c8b5d337 | ||
|
|
4aa20fd864 | ||
|
|
0cd4e46055 | ||
|
|
f51823b51f | ||
|
|
55bfeab208 | ||
|
|
309d15cefd | ||
|
|
95006a435a | ||
|
|
4d576ab4d4 | ||
|
|
d5b03ef60e | ||
|
|
cdc5b55a9d | ||
|
|
c3a38e3fea | ||
|
|
cc8c7e2cee | ||
|
|
e0f1787ce6 | ||
|
|
50e6108012 | ||
|
|
630ccfcacc | ||
|
|
c4c26058ef | ||
|
|
8a4da542ae | ||
|
|
e907dbe7e6 | ||
|
|
22b485acd9 | ||
|
|
b8f222acf2 | ||
|
|
aabb2ecda7 | ||
|
|
dfabc070b9 | ||
|
|
da420cdda9 | ||
|
|
c6a46e4753 | ||
|
|
742dd6f597 | ||
|
|
6c3ff1d6f0 | ||
|
|
db57aa229f | ||
|
|
f7342ede69 | ||
|
|
b781ccde9c | ||
|
|
8f62b2bff2 | ||
|
|
7047be859c | ||
|
|
2785e2219a | ||
|
|
4b217fba00 | ||
|
|
3fae68bbab | ||
|
|
a2f20aa25c | ||
|
|
94b8b9a5cf | ||
|
|
bbd8b27fc7 | ||
|
|
6361635b55 | ||
|
|
d2da4cfc43 | ||
|
|
a1136b3a02 | ||
|
|
4dd74b31b9 | ||
|
|
bc0f6eb65d | ||
|
|
6737d3da18 | ||
|
|
eb0f773146 | ||
|
|
ebac84899e | ||
|
|
0b7a090a73 | ||
|
|
a95019f38d | ||
|
|
15948c1af6 | ||
|
|
e73eb74208 | ||
|
|
278c59b920 | ||
|
|
5a1eb858a9 | ||
|
|
3c1dfb1170 | ||
|
|
09a02eb9e9 | ||
|
|
2bd7281fa0 | ||
|
|
e12fcd3a0d | ||
|
|
4af84fcaf6 | ||
|
|
c607015a26 | ||
|
|
217515344e | ||
|
|
dcf409aecb | ||
|
|
2683b7c734 | ||
|
|
3a672d725a | ||
|
|
f484781693 | ||
|
|
97f5b07003 | ||
|
|
7481395353 | ||
|
|
033ef151ca | ||
|
|
3fec7f432c | ||
|
|
4887078423 | ||
|
|
91deaece47 | ||
|
|
03ad2a17b2 | ||
|
|
a4cca6b759 | ||
|
|
6105bba0a4 | ||
|
|
259095eae2 | ||
|
|
38a0706b18 | ||
|
|
c7ae12c2ed | ||
|
|
3331f9b28d | ||
|
|
def4104c53 | ||
|
|
4eb5331ddc | ||
|
|
3bb5c0bbe5 | ||
|
|
83aa952de2 | ||
|
|
e0d33f2399 | ||
|
|
194cbca0f2 | ||
|
|
1697cc32a3 | ||
|
|
f058f90340 | ||
|
|
ca4b0346cb | ||
|
|
8d692ded4a | ||
|
|
dc2253e718 | ||
|
|
d16c6aeb30 | ||
|
|
cdc40d36ff | ||
|
|
80c19878e0 | ||
|
|
18f395b853 | ||
|
|
75435be949 | ||
|
|
ce73bc58e5 | ||
|
|
70219d1071 | ||
|
|
e9e0bf7d84 | ||
|
|
3da1dccf73 | ||
|
|
e02101c676 | ||
|
|
ffc47054dd | ||
|
|
2169045377 | ||
|
|
277c6cb690 | ||
|
|
91a98b8082 | ||
|
|
6028a8b1a8 | ||
|
|
6749f25bbf | ||
|
|
f6b96e3778 | ||
|
|
3b8cd0a3cd | ||
|
|
2f27b5df8c | ||
|
|
400fba7f6f | ||
|
|
bfaadd4e51 | ||
|
|
d16b35ed0b | ||
|
|
633f8dcd72 | ||
|
|
98cad8ae69 | ||
|
|
2e53bb6690 | ||
|
|
e3d9716607 | ||
|
|
862c94401a | ||
|
|
3a6e27bc87 | ||
|
|
ec2d01ab40 | ||
|
|
e4ff723895 | ||
|
|
f9448c6cd4 | ||
|
|
0efae1fcb6 | ||
|
|
7cc7aa51aa |
@@ -1,9 +1,3 @@
|
||||
Dockerfile
|
||||
# Docs
|
||||
doc/
|
||||
# GitHub stuff
|
||||
.github
|
||||
.gitignore
|
||||
.travis.yml
|
||||
LICENSE
|
||||
README.md
|
||||
**
|
||||
!release-packages
|
||||
!ci
|
||||
|
||||
6
.editorconfig
Normal file
@@ -0,0 +1,6 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
trim_trailing_whitespace = true
|
||||
indent_size = 2
|
||||
31
.eslintrc.yaml
Normal file
@@ -0,0 +1,31 @@
|
||||
parser: "@typescript-eslint/parser"
|
||||
env:
|
||||
browser: true
|
||||
es6: true # Map, etc.
|
||||
mocha: true
|
||||
node: true
|
||||
|
||||
parserOptions:
|
||||
ecmaVersion: 2018
|
||||
sourceType: module
|
||||
|
||||
extends:
|
||||
- eslint:recommended
|
||||
- plugin:@typescript-eslint/recommended
|
||||
- plugin:import/recommended
|
||||
- plugin:import/typescript
|
||||
- plugin:prettier/recommended
|
||||
- prettier # Removes eslint rules that conflict with prettier.
|
||||
- prettier/@typescript-eslint # Remove conflicts again.
|
||||
|
||||
rules:
|
||||
# For overloads.
|
||||
no-dupe-class-members: off
|
||||
"@typescript-eslint/no-use-before-define": off
|
||||
"@typescript-eslint/no-non-null-assertion": off
|
||||
|
||||
settings:
|
||||
# Does not work with CommonJS unfortunately.
|
||||
import/ignore:
|
||||
- env-paths
|
||||
- xdg-basedir
|
||||
3
.github/CODEOWNERS
vendored
@@ -1,2 +1 @@
|
||||
* @coderasher @kylecarbs
|
||||
Dockerfile @nhooyr
|
||||
* @code-asher @nhooyr
|
||||
|
||||
22
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,22 +0,0 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Report problems and unexpected behavior.
|
||||
title: ''
|
||||
labels: 'bug'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
<!-- Please search existing issues to avoid creating duplicates. -->
|
||||
<!-- All extension-specific issues should be created with the `Extension Bug` template. -->
|
||||
|
||||
- `code-server` version: <!-- The version of code-server -->
|
||||
- OS Version: <!-- OS version, cloud provider, -->
|
||||
|
||||
## Description
|
||||
|
||||
<!-- Describes the problem here -->
|
||||
|
||||
## Steps to Reproduce
|
||||
|
||||
1. <!-- step 1: click ... -->
|
||||
1. <!-- step 2: ... -->
|
||||
22
.github/ISSUE_TEMPLATE/extension_bug.md
vendored
@@ -1,22 +0,0 @@
|
||||
---
|
||||
name: Extension Bug
|
||||
about: Report problems and unexpected behavior with extensions.
|
||||
title: ''
|
||||
labels: 'extension-specific'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
<!-- Please search existing issues to avoid creating duplicates. -->
|
||||
|
||||
- `code-server` version: <!-- The version of code-server -->
|
||||
- OS Version: <!-- OS version, cloud provider, -->
|
||||
- Extension: <!-- Link to extension -->
|
||||
|
||||
## Description
|
||||
|
||||
<!-- Describes the problem here -->
|
||||
|
||||
## Steps to Reproduce
|
||||
|
||||
1. <!-- step 1: click ... -->
|
||||
1. <!-- step 2: ... -->
|
||||
11
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,11 +0,0 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Suggest an idea for this project.
|
||||
title: ''
|
||||
labels: 'feature'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
<!-- Please search existing issues to avoid creating duplicates. -->
|
||||
|
||||
<!-- Describe the feature you'd like. -->
|
||||
17
.github/ISSUE_TEMPLATE/question.md
vendored
@@ -1,17 +0,0 @@
|
||||
---
|
||||
name: Question
|
||||
about: Ask a question.
|
||||
title: ''
|
||||
labels: 'question'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
<!-- Please search existing issues to avoid creating duplicates. -->
|
||||
|
||||
## Description
|
||||
|
||||
<!-- A description of the the question. -->
|
||||
|
||||
## Related Issues
|
||||
|
||||
<!-- Any issues related to your question. -->
|
||||
11
.github/issue_template.md
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<!--
|
||||
Please file all questions and support requests at https://www.reddit.com/r/codeserver/
|
||||
The issue tracker is only for bugs.
|
||||
|
||||
Please see https://github.com/cdr/code-server/blob/master/doc/FAQ.md#how-do-i-debug-issues-with-code-server
|
||||
and include any logging information relevant to the issue.
|
||||
|
||||
Please search for existing issues before filing.
|
||||
|
||||
Please ensure you cannot reproduce on VS Code before filing.
|
||||
-->
|
||||
10
.github/pull_request_template.md
vendored
@@ -1,6 +1,4 @@
|
||||
<!-- Please answer these questions before submitting your PR. Thanks! -->
|
||||
|
||||
### Describe in detail the problem you had and how this PR fixes it
|
||||
|
||||
### Is there an open issue you can link to?
|
||||
|
||||
<!--
|
||||
Please link to the issue this PR solves.
|
||||
If there is no existing issue, please first create one unless the fix is minor.
|
||||
-->
|
||||
|
||||
148
.github/workflows/ci.yaml
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
name: ci
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
fmt:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Run ./ci/steps/fmt.sh
|
||||
uses: ./ci/container
|
||||
with:
|
||||
args: ./ci/steps/fmt.sh
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Run ./ci/steps/lint.sh
|
||||
uses: ./ci/container
|
||||
with:
|
||||
args: ./ci/steps/lint.sh
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Run ./ci/steps/test.sh
|
||||
uses: ./ci/container
|
||||
with:
|
||||
args: ./ci/steps/test.sh
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Run ./ci/steps/release.sh
|
||||
uses: ./ci/container
|
||||
with:
|
||||
args: ./ci/steps/release.sh
|
||||
- name: Upload npm package artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: npm-package
|
||||
path: ./release
|
||||
|
||||
linux-amd64:
|
||||
needs: release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Download npm package
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: npm-package
|
||||
path: ./release
|
||||
- name: Run ./ci/steps/release-static.sh
|
||||
uses: ./ci/container
|
||||
with:
|
||||
args: ./ci/steps/release-static.sh
|
||||
- name: Upload release artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: release-packages
|
||||
path: ./release-packages
|
||||
|
||||
linux-arm64:
|
||||
needs: release
|
||||
runs-on: ubuntu-arm64-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Download npm package
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: npm-package
|
||||
path: ./release
|
||||
- name: Run ./ci/steps/release-static.sh
|
||||
uses: ./ci/container
|
||||
with:
|
||||
args: ./ci/steps/release-static.sh
|
||||
- name: Upload release artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: release-packages
|
||||
path: ./release-packages
|
||||
|
||||
macos-amd64:
|
||||
needs: release
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Download npm package
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: npm-package
|
||||
path: ./release
|
||||
- run: brew unlink node@12
|
||||
- run: brew install node
|
||||
- run: ./ci/steps/release-static.sh
|
||||
env:
|
||||
# Otherwise we get rate limited when fetching the ripgrep binary.
|
||||
# For whatever reason only MacOS needs it.
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Upload release artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: release-packages
|
||||
path: ./release-packages
|
||||
|
||||
docker-amd64:
|
||||
runs-on: ubuntu-latest
|
||||
needs: linux-amd64
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Download release package
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: release-packages
|
||||
path: ./release-packages
|
||||
- name: Run ./ci/steps/build-docker-image.sh
|
||||
uses: ./ci/container
|
||||
with:
|
||||
args: ./ci/steps/build-docker-image.sh
|
||||
- name: Upload release image
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: release-images
|
||||
path: ./release-images
|
||||
|
||||
docker-arm64:
|
||||
runs-on: ubuntu-arm64-latest
|
||||
needs: linux-arm64
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Download release package
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: release-packages
|
||||
path: ./release-packages
|
||||
- name: Run ./ci/steps/build-docker-image.sh
|
||||
uses: ./ci/container
|
||||
with:
|
||||
args: ./ci/steps/build-docker-image.sh
|
||||
- name: Upload release image
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: release-images
|
||||
path: ./release-images
|
||||
31
.github/workflows/publish.yaml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: publish
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
npm:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Run ./ci/steps/publish-npm.sh
|
||||
uses: ./ci/container
|
||||
with:
|
||||
args: ./ci/steps/publish-npm.sh
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Run ./ci/steps/push-docker-manifest.sh
|
||||
uses: ./ci/container
|
||||
with:
|
||||
args: ./ci/steps/push-docker-manifest.sh
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
||||
14
.gitignore
vendored
@@ -1,6 +1,10 @@
|
||||
lib
|
||||
.tsbuildinfo
|
||||
.cache
|
||||
dist*
|
||||
out*
|
||||
release/
|
||||
release-static/
|
||||
release-packages/
|
||||
release-gcp/
|
||||
release-images/
|
||||
node_modules
|
||||
dist
|
||||
out
|
||||
.DS_Store
|
||||
release
|
||||
|
||||
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "lib/vscode"]
|
||||
path = lib/vscode
|
||||
url = https://github.com/microsoft/vscode
|
||||
4
.prettierrc.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
printWidth: 120
|
||||
semi: false
|
||||
trailingComma: all
|
||||
arrowParens: always
|
||||
2
.stylelintrc.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
extends:
|
||||
- stylelint-config-recommended
|
||||
38
.travis.yml
@@ -1,38 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 8.15.0
|
||||
env:
|
||||
- VERSION="1.32.0-$TRAVIS_BUILD_NUMBER"
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: ubuntu
|
||||
- os: osx
|
||||
before_install:
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install libxkbfile-dev
|
||||
libsecret-1-dev; fi
|
||||
script:
|
||||
- scripts/build.sh
|
||||
before_deploy:
|
||||
- echo "$VERSION" "$TRAVIS_COMMIT"
|
||||
- git config --local user.name "$USER_NAME"
|
||||
- git config --local user.email "$USER_EMAIL"
|
||||
- git tag "$VERSION" "$TRAVIS_COMMIT"
|
||||
- yarn task package "$VERSION"
|
||||
deploy:
|
||||
provider: releases
|
||||
file_glob: true
|
||||
draft: true
|
||||
tag_name: "$VERSION"
|
||||
target_commitish: "$TRAVIS_COMMIT"
|
||||
name: "$VERSION"
|
||||
skip_cleanup: true
|
||||
api_key:
|
||||
secure: YL/x24KjYjgYXPcJWk3FV7FGxI79Mh6gBECQEcdlf3fkLEoKFVgzHBoUNWrFPzyR4tgLyWNAgcpD9Lkme1TRWTom7UPjXcwMNyLcLa+uec7ciSAnYD9ntLTpiCuPDD1u0LtRGclSi/EHQ+F8YVq+HZJpXTsJeAmOmihma3GVbGKSZr+BRum+0YZSG4w+o4TOlYzw/4bLWS52MogZcwpjd+hemBbgXLuGU2ziKv2vEKCZFbEeA16II4x1WLI4mutDdCeh7+3aLzGLwDa49NxtsVYNjyNFF75JhCTCNA55e2YMiLz9Uq69IXe/mi5F7xUaFfhIqqLNyKBnKeEOzu3dYnc+8n3LjnQ+00PmkF05nx9kBn3UfV1kwQGh6QbyDmTtBP07rtUMyI14aeQqHjxsaVRdMnwj9Q2DjXRr8UDqESZF0rmK3pHCXS2fBhIzLE8tLVW5Heiba2pQRFMHMZW+KBE97FzcFh7is90Ait3T8enfcd/PWFPYoBejDAdjwxwOkezh5N5ZkYquEfDYuWrFi6zRFCktsruaAcA+xGtTf9oilBBzUqu8Ie+YFWH5me83xakcblJWdaW/D2rLJAJH3m6LFm8lBqyUgDX5t/etob6CpDuYHu5D1J3XINOj/+aLAcadq6qlh70PMZS3zYffUu3JlzaD2amlSHIT8b5YXFc=
|
||||
file:
|
||||
- release/*.tar.gz
|
||||
- release/*.zip
|
||||
on:
|
||||
repo: codercom/code-server
|
||||
branch: master
|
||||
cache: yarn
|
||||
31
Dockerfile
@@ -1,31 +0,0 @@
|
||||
FROM node:8.15.0
|
||||
|
||||
# Install VS Code's deps. These are the only two it seems we need.
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libxkbfile-dev \
|
||||
libsecret-1-dev
|
||||
|
||||
# Ensure latest yarn.
|
||||
RUN npm install -g yarn@1.13
|
||||
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
|
||||
# In the future, we can use https://github.com/yarnpkg/rfcs/pull/53 to make yarn use the node_modules
|
||||
# directly which should be fast as it is slow because it populates its own cache every time.
|
||||
RUN yarn && yarn task build:server:binary
|
||||
|
||||
# We deploy with ubuntu so that devs have a familiar environment.
|
||||
FROM ubuntu:18.10
|
||||
WORKDIR /root/project
|
||||
COPY --from=0 /src/packages/server/cli-linux-x64 /usr/local/bin/code-server
|
||||
EXPOSE 8443
|
||||
RUN apt-get update && apt-get install -y \
|
||||
openssl \
|
||||
net-tools
|
||||
RUN apt-get install -y locales && \
|
||||
locale-gen en_US.UTF-8
|
||||
# We unfortunately cannot use update-locale because docker will not use the env variables
|
||||
# configured in /etc/default/locale so we need to set it manually.
|
||||
ENV LANG=en_US.UTF-8
|
||||
ENTRYPOINT ["code-server"]
|
||||
128
README.md
@@ -1,79 +1,105 @@
|
||||
# code-server
|
||||
|
||||
[](https://github.com/codercom/code-server/issues)
|
||||
[](https://github.com/codercom/code-server/releases/latest)
|
||||
[](#)
|
||||
[](https://discord.gg/zxSwN8Z)
|
||||
Run [VS Code](https://github.com/Microsoft/vscode) on any machine anywhere and access it in the browser.
|
||||
|
||||
`code-server` is [VS Code](https://github.com/Microsoft/vscode) running on a remote server, accessible through the browser.
|
||||
- **Code everywhere:** Code on your Chromebook, tablet, and laptop with a
|
||||
consistent dev environment. Develop on a Linux machine and pick up from any
|
||||
device with a web browser.
|
||||
- **Server-powered:** Take advantage of large cloud servers to speed up tests, compilations, downloads, and more.
|
||||
Preserve battery life when you're on the go since all intensive tasks runs on your server.
|
||||
Make use of a spare computer you have lying around and turn it into a full development environment.
|
||||
|
||||

|
||||
|
||||
## Getting started
|
||||
|
||||
For a full setup and walkthrough, please see [./doc/guide.md](./doc/guide.md).
|
||||
|
||||
### Debian, Ubuntu
|
||||
|
||||
Try it out:
|
||||
```bash
|
||||
docker run -t -p 127.0.0.1:8443:8443 -v "${PWD}:/root/project" codercom/code-server --allow-http --no-auth
|
||||
curl -sSOL https://github.com/cdr/code-server/releases/download/3.3.0/code-server_3.3.0_amd64.deb
|
||||
sudo dpkg -i code-server_3.3.0_amd64.deb
|
||||
systemctl --user enable --now code-server
|
||||
# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml
|
||||
```
|
||||
|
||||
- Code on your Chromebook, tablet, and laptop with a consistent dev environment.
|
||||
- If you have a Windows or Mac workstation, more easily develop for Linux.
|
||||
- Take advantage of large cloud servers to speed up tests, compilations, downloads, and more.
|
||||
- Preserve battery life when you're on the go.
|
||||
- All intensive computation runs on your server.
|
||||
- You're no longer running excess instances of Chrome.
|
||||
### Fedora, Red Hat, SUSE
|
||||
|
||||

|
||||
```bash
|
||||
curl -sSOL https://github.com/cdr/code-server/releases/download/3.3.0/code-server-3.3.0-amd64.rpm
|
||||
sudo yum install -y code-server-3.3.0-amd64.rpm
|
||||
systemctl --user enable --now code-server
|
||||
# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
### npm
|
||||
|
||||
### Hosted
|
||||
We recommend installing from `npm` if we don't have a precompiled release for your machine's
|
||||
platform or architecture.
|
||||
|
||||
[Try `code-server` now](https://coder.com/signup) for free at coder.com.
|
||||
**note:** Installing via `npm` builds native modules on install and so requires C dependencies.
|
||||
See [./doc/npm.md](./doc/npm.md) for installing these dependencies.
|
||||
|
||||
You will need at least node v12 installed. See [#1633](https://github.com/cdr/code-server/issues/1633).
|
||||
|
||||
```bash
|
||||
npm install -g code-server
|
||||
code-server
|
||||
# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml
|
||||
```
|
||||
|
||||
### macOS
|
||||
|
||||
```bash
|
||||
brew install code-server
|
||||
brew services start code-server
|
||||
# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
See docker oneliner mentioned above. Dockerfile is at [/Dockerfile](/Dockerfile).
|
||||
```bash
|
||||
# This will start a code-server container and expose it at http://127.0.0.1:8080.
|
||||
# It will also mount your current directory into the container as `/home/coder/project`
|
||||
# and forward your UID/GID so that all file system operations occur as your user outside
|
||||
# the container.
|
||||
docker run -it -p 127.0.0.1:8080:8080 \
|
||||
-v "$PWD:/home/coder/project" \
|
||||
-u "$(id -u):$(id -g)" \
|
||||
codercom/code-server:latest
|
||||
```
|
||||
|
||||
### Binaries
|
||||
### Static releases
|
||||
|
||||
1. [Download a binary](https://github.com/codercom/code-server/releases) (Linux and OSX supported. Windows coming soon)
|
||||
2. Start the binary with the project directory as the first argument
|
||||
We publish self contained `.tar.gz` archives for every release on [github](https://github.com/cdr/code-server/releases).
|
||||
They bundle the node binary and compiled native modules.
|
||||
|
||||
```
|
||||
code-server <initial directory to open>
|
||||
```
|
||||
> You will be prompted to enter the password shown in the CLI
|
||||
`code-server` should now be running at https://localhost:8443.
|
||||
1. Download the latest release archive for your system from [github](https://github.com/cdr/code-server/releases).
|
||||
2. Unpack the release.
|
||||
3. You can run code-server by executing `./bin/code-server`.
|
||||
|
||||
> code-server uses a self-signed SSL certificate that may prompt your browser to ask you some additional questions before you proceed. Please [read here](doc/self-hosted/index.md) for more information.
|
||||
Add the code-server `bin` directory to your `$PATH` to easily execute `code-server` without the full path every time.
|
||||
|
||||
For detailed instructions and troubleshooting, see the [self-hosted quick start guide](doc/self-hosted/index.md).
|
||||
Here is an example script for installing and using a static `code-server` release on Linux:
|
||||
|
||||
Quickstart guides for [Google Cloud](doc/admin/install/google_cloud.md), [AWS](doc/admin/install/aws.md), and [Digital Ocean](doc/admin/install/digitalocean.md).
|
||||
```bash
|
||||
curl -sSL https://github.com/cdr/code-server/releases/download/3.3.0/code-server-3.3.0-linux-amd64.tar.gz | sudo tar -C /usr/local -xz
|
||||
sudo mv /usr/local/code-server-3.3.0-linux-amd64 /usr/local/code-server
|
||||
PATH="$PATH:/usr/local/code-server/bin"
|
||||
code-server
|
||||
# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml
|
||||
```
|
||||
|
||||
How to [secure your setup](/doc/security/ssl.md).
|
||||
## FAQ
|
||||
|
||||
## Development
|
||||
|
||||
### Known Issues
|
||||
|
||||
- Creating custom VS Code extensions and debugging them doesn't work.
|
||||
|
||||
### Future
|
||||
|
||||
- Windows support.
|
||||
- Electron and ChromeOS applications to bridge the gap between local<->remote.
|
||||
- Run VS Code unit tests against our builds to ensure features work as expected.
|
||||
See [./doc/FAQ.md](./doc/FAQ.md).
|
||||
|
||||
## Contributing
|
||||
|
||||
Development guides are coming soon.
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
See [./doc/CONTRIBUTING.md](./doc/CONTRIBUTING.md).
|
||||
|
||||
## Enterprise
|
||||
|
||||
Visit [our enterprise page](https://coder.com/enterprise) for more information about our enterprise offering.
|
||||
|
||||
## Commercialization
|
||||
|
||||
If you would like to commercialize code-server, please contact contact@coder.com.
|
||||
Visit [our website](https://coder.com) for more information about our
|
||||
enterprise offerings.
|
||||
|
||||
296
build/tasks.ts
@@ -1,296 +0,0 @@
|
||||
import { register, run } from "@coder/runner";
|
||||
import * as fs from "fs";
|
||||
import * as fse from "fs-extra";
|
||||
import * as os from "os";
|
||||
import * as path from "path";
|
||||
import * as zlib from "zlib";
|
||||
|
||||
const isWin = os.platform() === "win32";
|
||||
const libPath = path.join(__dirname, "../lib");
|
||||
const vscodePath = path.join(libPath, "vscode");
|
||||
const pkgsPath = path.join(__dirname, "../packages");
|
||||
const defaultExtensionsPath = path.join(libPath, "VSCode-linux-x64/resources/app/extensions");
|
||||
const vscodeVersion = "1.32.0";
|
||||
|
||||
const buildServerBinary = register("build:server:binary", async (runner) => {
|
||||
await ensureInstalled();
|
||||
await copyForDefaultExtensions();
|
||||
await Promise.all([
|
||||
buildBootstrapFork(),
|
||||
buildWeb(),
|
||||
buildDefaultExtensions(),
|
||||
buildServerBundle(),
|
||||
buildAppBrowser(),
|
||||
]);
|
||||
|
||||
await buildServerBinaryPackage();
|
||||
});
|
||||
|
||||
const buildServerBinaryPackage = register("build:server:binary:package", async (runner) => {
|
||||
const cliPath = path.join(pkgsPath, "server");
|
||||
runner.cwd = cliPath;
|
||||
if (!fs.existsSync(path.join(cliPath, "out"))) {
|
||||
throw new Error("Cannot build binary without server bundle built");
|
||||
}
|
||||
await buildServerBinaryCopy();
|
||||
await dependencyNexeBinary();
|
||||
const resp = await runner.execute(isWin ? "npm.cmd" : "npm", ["run", "build:nexe"]);
|
||||
if (resp.exitCode !== 0) {
|
||||
throw new Error(`Failed to package binary: ${resp.stderr}`);
|
||||
}
|
||||
});
|
||||
|
||||
const dependencyNexeBinary = register("dependency:nexe", async (runner) => {
|
||||
if (os.platform() === "linux" && process.env.COMPRESS === "true") {
|
||||
// Download the nexe binary so we can compress it before nexe runs. If we
|
||||
// don't want compression we don't need to do anything since nexe will take
|
||||
// care of getting the binary.
|
||||
const nexeDir = path.join(os.homedir(), ".nexe");
|
||||
const targetBinaryName = `${os.platform()}-${os.arch()}-${process.version.substr(1)}`;
|
||||
const targetBinaryPath = path.join(nexeDir, targetBinaryName);
|
||||
if (!fs.existsSync(targetBinaryPath)) {
|
||||
fse.mkdirpSync(nexeDir);
|
||||
runner.cwd = nexeDir;
|
||||
await runner.execute("wget", [`https://github.com/nexe/nexe/releases/download/v3.0.0-beta.15/${targetBinaryName}`]);
|
||||
await runner.execute("chmod", ["+x", targetBinaryPath]);
|
||||
}
|
||||
// Compress with upx if it doesn't already look compressed.
|
||||
if (fs.statSync(targetBinaryPath).size >= 20000000) {
|
||||
// It needs to be executable for upx to work, which it might not be if
|
||||
// nexe downloaded it.
|
||||
fs.chmodSync(targetBinaryPath, "755");
|
||||
const upxFolder = path.join(os.tmpdir(), "upx");
|
||||
const upxBinary = path.join(upxFolder, "upx");
|
||||
if (!fs.existsSync(upxBinary)) {
|
||||
fse.mkdirpSync(upxFolder);
|
||||
runner.cwd = upxFolder;
|
||||
const upxExtract = await runner.execute("bash", ["-c", "curl -L https://github.com/upx/upx/releases/download/v3.95/upx-3.95-amd64_linux.tar.xz | tar xJ --strip-components=1"]);
|
||||
if (upxExtract.exitCode !== 0) {
|
||||
throw new Error(`Failed to extract upx: ${upxExtract.stderr}`);
|
||||
}
|
||||
}
|
||||
if (!fs.existsSync(upxBinary)) {
|
||||
throw new Error("Not sure how, but the UPX binary does not exist");
|
||||
}
|
||||
await runner.execute(upxBinary, [targetBinaryPath]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const buildServerBinaryCopy = register("build:server:binary:copy", async (runner) => {
|
||||
const cliPath = path.join(pkgsPath, "server");
|
||||
const cliBuildPath = path.join(cliPath, "build");
|
||||
fse.removeSync(cliBuildPath);
|
||||
fse.mkdirpSync(path.join(cliBuildPath, "extensions"));
|
||||
const bootstrapForkPath = path.join(pkgsPath, "vscode", "out", "bootstrap-fork.js");
|
||||
const webOutputPath = path.join(pkgsPath, "web", "out");
|
||||
const browserAppOutputPath = path.join(pkgsPath, "app", "browser", "out");
|
||||
const nodePtyModule = path.join(pkgsPath, "protocol", "node_modules", "node-pty-prebuilt", "build", "Release", "pty.node");
|
||||
const spdlogModule = path.join(pkgsPath, "protocol", "node_modules", "spdlog", "build", "Release", "spdlog.node");
|
||||
let ripgrepPath = path.join(pkgsPath, "..", "lib", "vscode", "node_modules", "vscode-ripgrep", "bin", "rg");
|
||||
if (isWin) {
|
||||
ripgrepPath += ".exe";
|
||||
}
|
||||
|
||||
if (!fs.existsSync(nodePtyModule)) {
|
||||
throw new Error("Could not find pty.node. Ensure all packages have been installed");
|
||||
}
|
||||
if (!fs.existsSync(spdlogModule)) {
|
||||
throw new Error("Could not find spdlog.node. Ensure all packages have been installed");
|
||||
}
|
||||
if (!fs.existsSync(webOutputPath)) {
|
||||
throw new Error("Web bundle must be built");
|
||||
}
|
||||
if (!fs.existsSync(defaultExtensionsPath)) {
|
||||
throw new Error("Default extensions must be built");
|
||||
}
|
||||
if (!fs.existsSync(bootstrapForkPath)) {
|
||||
throw new Error("Bootstrap fork must exist");
|
||||
}
|
||||
if (!fs.existsSync(ripgrepPath)) {
|
||||
throw new Error("Ripgrep must exist");
|
||||
}
|
||||
fse.copySync(defaultExtensionsPath, path.join(cliBuildPath, "extensions"));
|
||||
fs.writeFileSync(path.join(cliBuildPath, "bootstrap-fork.js.gz"), zlib.gzipSync(fs.readFileSync(bootstrapForkPath)));
|
||||
const cpDir = (dir: string, subdir: "auth" | "unauth", rootPath: string): void => {
|
||||
const stat = fs.statSync(dir);
|
||||
if (stat.isDirectory()) {
|
||||
const paths = fs.readdirSync(dir);
|
||||
paths.forEach((p) => cpDir(path.join(dir, p), subdir, rootPath));
|
||||
} else if (stat.isFile()) {
|
||||
const newPath = path.join(cliBuildPath, "web", subdir, path.relative(rootPath, dir));
|
||||
fse.mkdirpSync(path.dirname(newPath));
|
||||
fs.writeFileSync(newPath + ".gz", zlib.gzipSync(fs.readFileSync(dir)));
|
||||
} else {
|
||||
// Nothing
|
||||
}
|
||||
};
|
||||
cpDir(webOutputPath, "auth", webOutputPath);
|
||||
cpDir(browserAppOutputPath, "unauth", browserAppOutputPath);
|
||||
fse.mkdirpSync(path.join(cliBuildPath, "dependencies"));
|
||||
fse.copySync(nodePtyModule, path.join(cliBuildPath, "dependencies", "pty.node"));
|
||||
fse.copySync(spdlogModule, path.join(cliBuildPath, "dependencies", "spdlog.node"));
|
||||
fse.copySync(ripgrepPath, path.join(cliBuildPath, "dependencies", "rg"));
|
||||
});
|
||||
|
||||
const buildServerBundle = register("build:server:bundle", async (runner) => {
|
||||
const cliPath = path.join(pkgsPath, "server");
|
||||
runner.cwd = cliPath;
|
||||
await runner.execute(isWin ? "npm.cmd" : "npm", ["run", "build"]);
|
||||
});
|
||||
|
||||
const buildBootstrapFork = register("build:bootstrap-fork", async (runner) => {
|
||||
await ensureInstalled();
|
||||
await ensurePatched();
|
||||
|
||||
const vscodePkgPath = path.join(pkgsPath, "vscode");
|
||||
runner.cwd = vscodePkgPath;
|
||||
await runner.execute(isWin ? "npm.cmd" : "npm", ["run", "build:bootstrap-fork"]);
|
||||
});
|
||||
|
||||
const buildAppBrowser = register("build:app:browser", async (runner) => {
|
||||
await ensureInstalled();
|
||||
|
||||
const appPath = path.join(pkgsPath, "app/browser");
|
||||
runner.cwd = appPath;
|
||||
fse.removeSync(path.join(appPath, "out"));
|
||||
await runner.execute(isWin ? "npm.cmd" : "npm", ["run", "build"]);
|
||||
});
|
||||
|
||||
const buildWeb = register("build:web", async (runner) => {
|
||||
await ensureInstalled();
|
||||
await ensurePatched();
|
||||
|
||||
const webPath = path.join(pkgsPath, "web");
|
||||
runner.cwd = webPath;
|
||||
fse.removeSync(path.join(webPath, "out"));
|
||||
await runner.execute(isWin ? "npm.cmd" : "npm", ["run", "build"]);
|
||||
});
|
||||
|
||||
const extDirPath = path.join("lib", "vscode-default-extensions");
|
||||
const copyForDefaultExtensions = register("build:copy-vscode", async (runner) => {
|
||||
if (!fs.existsSync(defaultExtensionsPath)) {
|
||||
await ensureClean();
|
||||
await ensureInstalled();
|
||||
await new Promise((resolve, reject): void => {
|
||||
fse.remove(extDirPath, (err) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
await new Promise((resolve, reject): void => {
|
||||
fse.copy(vscodePath, extDirPath, (err) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const buildDefaultExtensions = register("build:default-extensions", async (runner) => {
|
||||
if (!fs.existsSync(defaultExtensionsPath)) {
|
||||
await copyForDefaultExtensions();
|
||||
runner.cwd = extDirPath;
|
||||
const resp = await runner.execute(isWin ? "npx.cmd" : "npx", [isWin ? "gulp.cmd" : "gulp", "vscode-linux-x64", "--max-old-space-size=32384"]);
|
||||
if (resp.exitCode !== 0) {
|
||||
throw new Error(`Failed to build default extensions: ${resp.stderr}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const ensureInstalled = register("vscode:install", async (runner) => {
|
||||
await ensureCloned();
|
||||
|
||||
runner.cwd = vscodePath;
|
||||
const install = await runner.execute(isWin ? "yarn.cmd" : "yarn", []);
|
||||
if (install.exitCode !== 0) {
|
||||
throw new Error(`Failed to install vscode dependencies: ${install.stderr}`);
|
||||
}
|
||||
});
|
||||
|
||||
const ensureCloned = register("vscode:clone", async (runner) => {
|
||||
if (fs.existsSync(vscodePath)) {
|
||||
await ensureClean();
|
||||
} else {
|
||||
fse.mkdirpSync(libPath);
|
||||
runner.cwd = libPath;
|
||||
const clone = await runner.execute("git", ["clone", "https://github.com/microsoft/vscode", "--branch", vscodeVersion, "--single-branch", "--depth=1"]);
|
||||
if (clone.exitCode !== 0) {
|
||||
throw new Error(`Failed to clone: ${clone.exitCode}`);
|
||||
}
|
||||
}
|
||||
|
||||
runner.cwd = vscodePath;
|
||||
const checkout = await runner.execute("git", ["checkout", vscodeVersion]);
|
||||
if (checkout.exitCode !== 0) {
|
||||
throw new Error(`Failed to checkout: ${checkout.stderr}`);
|
||||
}
|
||||
});
|
||||
|
||||
const ensureClean = register("vscode:clean", async (runner) => {
|
||||
runner.cwd = vscodePath;
|
||||
|
||||
const status = await runner.execute("git", ["status", "--porcelain"]);
|
||||
if (status.stdout.trim() !== "") {
|
||||
const clean = await runner.execute("git", ["clean", "-f", "-d", "-X"]);
|
||||
if (clean.exitCode !== 0) {
|
||||
throw new Error(`Failed to clean git repository: ${clean.stderr}`);
|
||||
}
|
||||
const removeUnstaged = await runner.execute("git", ["checkout", "--", "."]);
|
||||
if (removeUnstaged.exitCode !== 0) {
|
||||
throw new Error(`Failed to remove unstaged files: ${removeUnstaged.stderr}`);
|
||||
}
|
||||
}
|
||||
const fetch = await runner.execute("git", ["fetch", "--prune"]);
|
||||
if (fetch.exitCode !== 0) {
|
||||
throw new Error(`Failed to fetch latest changes: ${fetch.stderr}`);
|
||||
}
|
||||
});
|
||||
|
||||
const ensurePatched = register("vscode:patch", async (runner) => {
|
||||
if (!fs.existsSync(vscodePath)) {
|
||||
throw new Error("vscode must be cloned to patch");
|
||||
}
|
||||
await ensureClean();
|
||||
|
||||
runner.cwd = vscodePath;
|
||||
const patchPath = path.join(__dirname, "../scripts/vscode.patch");
|
||||
const apply = await runner.execute("git", ["apply", "--unidiff-zero", patchPath]);
|
||||
if (apply.exitCode !== 0) {
|
||||
throw new Error(`Failed to apply patches: ${apply.stderr}`);
|
||||
}
|
||||
});
|
||||
|
||||
register("package", async (runner, releaseTag) => {
|
||||
if (!releaseTag) {
|
||||
throw new Error("Please specify the release tag.");
|
||||
}
|
||||
|
||||
const releasePath = path.resolve(__dirname, "../release");
|
||||
|
||||
const archiveName = `code-server-${releaseTag}-${os.platform()}-${os.arch()}`;
|
||||
const archiveDir = path.join(releasePath, archiveName);
|
||||
fse.removeSync(archiveDir);
|
||||
fse.mkdirpSync(archiveDir);
|
||||
|
||||
const binaryPath = path.join(__dirname, `../packages/server/cli-${os.platform()}-${os.arch()}`);
|
||||
const binaryDestination = path.join(archiveDir, "code-server");
|
||||
fse.copySync(binaryPath, binaryDestination);
|
||||
fs.chmodSync(binaryDestination, "755");
|
||||
["README.md", "LICENSE"].forEach((fileName) => {
|
||||
fse.copySync(path.resolve(__dirname, `../${fileName}`), path.join(archiveDir, fileName));
|
||||
});
|
||||
|
||||
runner.cwd = releasePath;
|
||||
await os.platform() === "linux"
|
||||
? runner.execute("tar", ["-cvzf", `${archiveName}.tar.gz`, `${archiveName}`])
|
||||
: runner.execute("zip", ["-r", `${archiveName}.zip`, `${archiveName}`]);
|
||||
});
|
||||
|
||||
run();
|
||||
136
ci/README.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# ci
|
||||
|
||||
This directory contains scripts used for code-server's continuous integration infrastructure.
|
||||
|
||||
Some of these scripts contain more detailed documentation and options
|
||||
in header comments.
|
||||
|
||||
Any file or directory in this subdirectory should be documented here.
|
||||
|
||||
- [./ci/lib.sh](./lib.sh)
|
||||
- Contains code duplicated across these scripts.
|
||||
|
||||
## Publishing a release
|
||||
|
||||
Make sure you have `$GITHUB_TOKEN` set and [hub](https://github.com/github/hub) installed.
|
||||
|
||||
1. Update the version of code-server in `package.json` and README.md/guide.md install examples and push a commit.
|
||||
2. GitHub actions will generate the `npm-package`, `release-packages` and `release-images` artifacts.
|
||||
3. Run `yarn release:github-draft` to create a GitHub draft release from the template with
|
||||
the updated version.
|
||||
1. Summarize the major changes in the release notes and link to the relevant issues.
|
||||
4. Wait for the artifacts in step 2 to build.
|
||||
5. Run `yarn release:github-assets` to download the `release-packages` artifact and then
|
||||
upload them to the draft release.
|
||||
6. Run some basic sanity tests on one of the released packages.
|
||||
7. Publish the release.
|
||||
1. CI will automatically grab the artifacts and then:
|
||||
1. Publish the NPM package from `npm-package`.
|
||||
2. Publish the Docker Hub image from `release-images`.
|
||||
8. Update the homebrew and AUR packages.
|
||||
|
||||
## dev
|
||||
|
||||
This directory contains scripts used for the development of code-server.
|
||||
|
||||
- [./ci/dev/container](./dev/container)
|
||||
- See [./doc/CONTRIBUTING.md](../doc/CONTRIBUTING.md) for docs on the development container.
|
||||
- [./ci/dev/fmt.sh](./dev/fmt.sh) (`yarn fmt`)
|
||||
- Runs formatters.
|
||||
- [./ci/dev/lint.sh](./dev/lint.sh) (`yarn lint`)
|
||||
- Runs linters.
|
||||
- [./ci/dev/test.sh](./dev/test.sh) (`yarn test`)
|
||||
- Runs tests.
|
||||
- [./ci/dev/ci.sh](./dev/ci.sh) (`yarn ci`)
|
||||
- Runs `yarn fmt`, `yarn lint` and `yarn test`.
|
||||
- [./ci/dev/vscode.sh](./dev/vscode.sh) (`yarn vscode`)
|
||||
- Ensures [./lib/vscode](../lib/vscode) is cloned, patched and dependencies are installed.
|
||||
- [./ci/dev/patch-vscode.sh](./dev/patch-vscode.sh) (`yarn vscode:patch`)
|
||||
- Applies [./ci/dev/vscode.patch](./dev/vscode.patch) to [./lib/vscode](../lib/vscode).
|
||||
- [./ci/dev/diff-vscode.sh](./dev/diff-vscode.sh) (`yarn vscode:diff`)
|
||||
- Diffs [./lib/vscode](../lib/vscode) into [./ci/dev/vscode.patch](./dev/vscode.patch).
|
||||
- [./ci/dev/vscode.patch](./dev/vscode.patch)
|
||||
- Our patch of VS Code, see [./doc/CONTRIBUTING.md](../doc/CONTRIBUTING.md#vs-code-patch).
|
||||
- Generate it with `yarn vscode:diff` and apply with `yarn vscode:patch`.
|
||||
- [./ci/dev/watch.ts](./dev/watch.ts) (`yarn watch`)
|
||||
- Starts a process to build and launch code-server and restart on any code changes.
|
||||
- Example usage in [./doc/CONTRIBUTING.md](../doc/CONTRIBUTING.md).
|
||||
|
||||
## build
|
||||
|
||||
This directory contains the scripts used to build and release code-server.
|
||||
You can disable minification by setting `MINIFY=`.
|
||||
|
||||
- [./ci/build/build-code-server.sh](./build/build-code-server.sh) (`yarn build`)
|
||||
- Builds code-server into `./out` and bundles the frontend into `./dist`.
|
||||
- [./ci/build/build-vscode.sh](./build/build-vscode.sh) (`yarn build:vscode`)
|
||||
- Builds vscode into `./lib/vscode/out-vscode`.
|
||||
- [./ci/build/build-release.sh](./build/build-release.sh) (`yarn release`)
|
||||
- Bundles the output of the above two scripts into a single node module at `./release`.
|
||||
- [./ci/build/build-static-release.sh](./build/build-static-release.sh) (`yarn release:static`)
|
||||
- Requires a node module already built into `./release` with the above script.
|
||||
- Will build a static release with node and native modules bundled into `./release-static`.
|
||||
- [./ci/build/clean.sh](./build/clean.sh) (`yarn clean`)
|
||||
- Removes all build artifacts.
|
||||
- Will also `git reset --hard lib/vscode`.
|
||||
- Useful to do a clean build.
|
||||
- [./ci/build/code-server.sh](./build/code-server.sh)
|
||||
- Copied into static releases to run code-server with the bundled node binary.
|
||||
- [./ci/build/test-static-release.sh](./build/test-static-release.sh) (`yarn test:static-release`)
|
||||
- Ensures code-server in the `./release-static` directory works by installing an extension.
|
||||
- [./ci/build/build-packages.sh](./build/build-packages.sh) (`yarn package`)
|
||||
- Packages `./release-static` into a `.tar.gz` archive in `./release-packages`.
|
||||
- If on linux, [nfpm](https://github.com/goreleaser/nfpm) is used to generate `.deb` and `.rpm`.
|
||||
- [./ci/build/nfpm.yaml](./build/nfpm.yaml)
|
||||
- Used to configure [nfpm](https://github.com/goreleaser/nfpm) to generate `.deb` and `.rpm`.
|
||||
- [./ci/build/code-server-nfpm.sh](./build/code-server-nfpm.sh)
|
||||
- Entrypoint script for code-server for `.deb` and .rpm`.
|
||||
- [./ci/build/code-server.service](./build/code-server.service)
|
||||
- systemd user service packaged into the `.deb` and `.rpm`.
|
||||
- [./ci/build/release-github-draft.sh](./build/release-github-draft.sh) (`yarn release:github-draft`)
|
||||
- Uses [hub](https://github.com/github/hub) to create a draft release with a template description.
|
||||
- [./ci/build/release-github-assets.sh](./build/release-github-assets.sh) (`yarn release:github-assets`)
|
||||
- Downloads the release-package artifacts for the current commit from CI.
|
||||
- Uses [hub](https://github.com/github/hub) to upload the artifacts to the release
|
||||
specified in `package.json`.
|
||||
- [./ci/build/npm-postinstall.sh](./build/npm-postinstall.sh)
|
||||
- Post install script for the npm package.
|
||||
- Bundled by`yarn release`.
|
||||
|
||||
## release-container
|
||||
|
||||
This directory contains the release docker container.
|
||||
|
||||
- [./release-container/build.sh](./release-container/build.sh)
|
||||
- Builds the release container with the tag `codercom/code-server-$ARCH:$VERSION`.
|
||||
- Assumes debian releases are ready in `./release-packages`.
|
||||
|
||||
## container
|
||||
|
||||
This directory contains the container for CI.
|
||||
|
||||
## steps
|
||||
|
||||
This directory contains the scripts used in CI.
|
||||
Helps avoid clobbering the CI configuration.
|
||||
|
||||
- [./steps/fmt.sh](./steps/fmt.sh)
|
||||
- Runs `yarn fmt` after ensuring VS Code is patched.
|
||||
- [./steps/lint.sh](./steps/lint.sh)
|
||||
- Runs `yarn lint` after ensuring VS Code is patched.
|
||||
- [./steps/test.sh](./steps/test.sh)
|
||||
- Runs `yarn test` after ensuring VS Code is patched.
|
||||
- [./steps/release.sh](./steps/release.sh)
|
||||
- Runs the release process.
|
||||
- Generates the npm package at `./release`.
|
||||
- [./steps/release-static.sh](./steps/release-static.sh)
|
||||
- Takes the output of the previous script and generates a static release and
|
||||
release packages into `release-packages`.
|
||||
- [./steps/publish-npm.sh](./steps/publish-npm.sh)
|
||||
- Grabs the `npm-package` release artifact for the current commit and publishes it on npm.
|
||||
- [./steps/build-docker-image.sh](./steps/build-docker-image.sh)
|
||||
- Builds the docker image and then saves it into `./release-images/code-server-$ARCH-$VERSION.tar`.
|
||||
- [./steps/push-docker-manifest.sh](./steps/push-docker-manifest.sh)
|
||||
- Loads all images in `./release-images` and then builds and pushes a multi architecture
|
||||
docker manifest for the amd64 and arm64 images to `codercom/code-server:$VERSION` and
|
||||
`codercom/code-server:latest`.
|
||||
29
ci/build/build-code-server.sh
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Builds code-server into out and the frontend into dist.
|
||||
|
||||
# MINIFY controls whether parcel minifies dist.
|
||||
MINIFY=${MINIFY-true}
|
||||
|
||||
main() {
|
||||
cd "$(dirname "${0}")/../.."
|
||||
|
||||
npx tsc --outDir out --tsBuildInfoFile .cache/out.tsbuildinfo
|
||||
# If out/node/entry.js does not already have the shebang,
|
||||
# we make sure to add it and make it executable.
|
||||
if ! grep -q -m1 "^#!/usr/bin/env node" out/node/entry.js; then
|
||||
sed -i.bak "1s;^;#!/usr/bin/env node\n;" out/node/entry.js && rm out/node/entry.js.bak
|
||||
chmod +x out/node/entry.js
|
||||
fi
|
||||
|
||||
npx parcel build \
|
||||
--public-url "/static/$(git rev-parse HEAD)/dist" \
|
||||
--out-dir dist \
|
||||
$([[ $MINIFY ]] || echo --no-minify) \
|
||||
src/browser/pages/app.ts \
|
||||
src/browser/register.ts \
|
||||
src/browser/serviceWorker.ts
|
||||
}
|
||||
|
||||
main "$@"
|
||||
46
ci/build/build-packages.sh
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Packages code-server for the current OS and architecture into ./release-packages.
|
||||
# This script assumes that a static release is built already into ./release-static.
|
||||
|
||||
main() {
|
||||
cd "$(dirname "${0}")/../.."
|
||||
source ./ci/lib.sh
|
||||
|
||||
local release_name="code-server-$VERSION-$OS-$ARCH"
|
||||
mkdir -p release-packages
|
||||
|
||||
if [[ $OS == "linux" ]]; then
|
||||
tar -czf "release-packages/$release_name.tar.gz" --transform "s/^\.\/release-static/$release_name/" ./release-static
|
||||
else
|
||||
tar -czf "release-packages/$release_name.tar.gz" -s "/^release-static/$release_name/" release-static
|
||||
fi
|
||||
|
||||
echo "done (release-packages/$release_name)"
|
||||
|
||||
release_gcp
|
||||
|
||||
if [[ $OSTYPE == linux* ]]; then
|
||||
release_nfpm
|
||||
fi
|
||||
}
|
||||
|
||||
release_gcp() {
|
||||
mkdir -p "release-gcp/$VERSION"
|
||||
cp "release-packages/$release_name.tar.gz" "./release-gcp/$VERSION/$OS-$ARCH.tar.gz"
|
||||
mkdir -p "release-gcp/latest"
|
||||
cp "./release-packages/$release_name.tar.gz" "./release-gcp/latest/$OS-$ARCH.tar.gz"
|
||||
}
|
||||
|
||||
# Generates deb and rpm packages.
|
||||
release_nfpm() {
|
||||
local nfpm_config
|
||||
nfpm_config=$(envsubst < ./ci/build/nfpm.yaml)
|
||||
|
||||
# The underscores are convention for .deb.
|
||||
nfpm pkg -f <(echo "$nfpm_config") --target "release-packages/code-server_${VERSION}_${ARCH}.deb"
|
||||
nfpm pkg -f <(echo "$nfpm_config") --target "release-packages/code-server-$VERSION-$ARCH.rpm"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
93
ci/build/build-release.sh
Executable file
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# This script requires vscode to be built with matching MINIFY.
|
||||
|
||||
# MINIFY controls whether minified vscode is bundled.
|
||||
MINIFY="${MINIFY-true}"
|
||||
|
||||
main() {
|
||||
cd "$(dirname "${0}")/../.."
|
||||
source ./ci/lib.sh
|
||||
|
||||
VSCODE_SRC_PATH="lib/vscode"
|
||||
VSCODE_OUT_PATH="$RELEASE_PATH/lib/vscode"
|
||||
|
||||
mkdir -p "$RELEASE_PATH"
|
||||
|
||||
bundle_code_server
|
||||
bundle_vscode
|
||||
|
||||
rsync README.md "$RELEASE_PATH"
|
||||
rsync LICENSE.txt "$RELEASE_PATH"
|
||||
rsync ./lib/vscode/ThirdPartyNotices.txt "$RELEASE_PATH"
|
||||
}
|
||||
|
||||
bundle_code_server() {
|
||||
rsync out dist "$RELEASE_PATH"
|
||||
|
||||
# For source maps and images.
|
||||
mkdir -p "$RELEASE_PATH/src/browser"
|
||||
rsync src/browser/media/ "$RELEASE_PATH/src/browser/media"
|
||||
mkdir -p "$RELEASE_PATH/src/browser/pages"
|
||||
rsync src/browser/pages/*.html "$RELEASE_PATH/src/browser/pages"
|
||||
|
||||
# Adds the commit to package.json
|
||||
jq --slurp '.[0] * .[1]' package.json <(
|
||||
cat << EOF
|
||||
{
|
||||
"commit": "$(git rev-parse HEAD)",
|
||||
"scripts": {
|
||||
"postinstall": "./postinstall.sh"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
) > "$RELEASE_PATH/package.json"
|
||||
rsync yarn.lock "$RELEASE_PATH"
|
||||
rsync ci/build/npm-postinstall.sh "$RELEASE_PATH/postinstall.sh"
|
||||
}
|
||||
|
||||
bundle_vscode() {
|
||||
mkdir -p "$VSCODE_OUT_PATH"
|
||||
rsync "$VSCODE_SRC_PATH/package.json" "$VSCODE_OUT_PATH"
|
||||
rsync "$VSCODE_SRC_PATH/yarn.lock" "$VSCODE_OUT_PATH"
|
||||
rsync "$VSCODE_SRC_PATH/node_modules" "$VSCODE_OUT_PATH"
|
||||
rsync "$VSCODE_SRC_PATH/out-vscode${MINIFY+-min}/" "$VSCODE_OUT_PATH/out"
|
||||
rsync "$VSCODE_SRC_PATH/.build/extensions/" "$VSCODE_OUT_PATH/extensions"
|
||||
|
||||
mkdir -p "$VSCODE_OUT_PATH/resources/linux"
|
||||
rsync "$VSCODE_SRC_PATH/resources/linux/code.png" "$VSCODE_OUT_PATH/resources/linux/code.png"
|
||||
|
||||
# Adds the commit and date to product.json
|
||||
jq --slurp '.[0] * .[1]' "$VSCODE_SRC_PATH/product.json" <(
|
||||
cat << EOF
|
||||
{
|
||||
"commit": "$(git rev-parse HEAD)",
|
||||
"date": $(jq -n 'now | todate')
|
||||
}
|
||||
EOF
|
||||
) > "$VSCODE_OUT_PATH/product.json"
|
||||
|
||||
pushd "$VSCODE_OUT_PATH"
|
||||
yarn --production --frozen-lockfile --ignore-scripts
|
||||
popd
|
||||
|
||||
# We clear any native module builds.
|
||||
local native_modules
|
||||
mapfile -t native_modules < <(find "$VSCODE_OUT_PATH/node_modules" -name "binding.gyp" -exec dirname {} \;)
|
||||
local nm
|
||||
for nm in "${native_modules[@]}"; do
|
||||
rm -R "$nm/build"
|
||||
done
|
||||
|
||||
# We have to rename node_modules to node_modules.bundled to avoid them being ignored by yarn.
|
||||
local node_modules
|
||||
mapfile -t node_modules < <(find "$VSCODE_OUT_PATH" -depth -name "node_modules")
|
||||
local nm
|
||||
for nm in "${node_modules[@]}"; do
|
||||
rm -Rf "$nm.bundled"
|
||||
mv "$nm" "$nm.bundled"
|
||||
done
|
||||
}
|
||||
|
||||
main "$@"
|
||||
25
ci/build/build-static-release.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "${0}")/../.."
|
||||
source ./ci/lib.sh
|
||||
|
||||
rsync "$RELEASE_PATH/" "$RELEASE_PATH-static"
|
||||
RELEASE_PATH+=-static
|
||||
|
||||
# We cannot find the path to node from $PATH because yarn shims a script to ensure
|
||||
# we use the same version it's using so we instead run a script with yarn that
|
||||
# will print the path to node.
|
||||
local node_path
|
||||
node_path="$(yarn -s node <<< 'console.info(process.execPath)')"
|
||||
|
||||
mkdir -p "$RELEASE_PATH/bin"
|
||||
rsync ./ci/build/code-server.sh "$RELEASE_PATH/bin/code-server"
|
||||
rsync "$node_path" "$RELEASE_PATH/lib/node"
|
||||
|
||||
cd "$RELEASE_PATH"
|
||||
yarn --production --frozen-lockfile
|
||||
}
|
||||
|
||||
main "$@"
|
||||
21
ci/build/build-vscode.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Builds vscode into lib/vscode/out-vscode.
|
||||
|
||||
# MINIFY controls whether a minified version of vscode is built.
|
||||
MINIFY=${MINIFY-true}
|
||||
|
||||
main() {
|
||||
cd "$(dirname "${0}")/../.."
|
||||
cd lib/vscode
|
||||
|
||||
yarn gulp compile-build
|
||||
yarn gulp compile-extensions-build
|
||||
yarn gulp optimize --gulpfile ./coder.js
|
||||
if [[ $MINIFY ]]; then
|
||||
yarn gulp minify --gulpfile ./coder.js
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
24
ci/build/clean.sh
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "${0}")/../.."
|
||||
source ./ci/lib.sh
|
||||
|
||||
rm -Rf \
|
||||
out \
|
||||
release \
|
||||
release-static \
|
||||
release-packages \
|
||||
release-gcp \
|
||||
dist \
|
||||
.tsbuildinfo \
|
||||
.cache/out.tsbuildinfo
|
||||
|
||||
pushd lib/vscode
|
||||
git clean -xffd
|
||||
git reset --hard
|
||||
popd
|
||||
}
|
||||
|
||||
main "$@"
|
||||
3
ci/build/code-server-nfpm.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
exec /usr/lib/code-server/bin/code-server "$@"
|
||||
11
ci/build/code-server.service
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=code-server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
ExecStart=/usr/bin/code-server
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
20
ci/build/code-server.sh
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# This script is intended to be bundled into the static releases.
|
||||
# Runs code-server with the bundled Node binary.
|
||||
|
||||
# More complicated than readlink -f or realpath to support macOS.
|
||||
# See https://github.com/cdr/code-server/issues/1537
|
||||
bin_dir() {
|
||||
# We read the symlink, which may be relative from $0.
|
||||
dst="$(readlink "$0")"
|
||||
# We cd into the $0 directory.
|
||||
cd "$(dirname "$0")" || exit 1
|
||||
# Now we can cd into the dst directory.
|
||||
cd "$(dirname "$dst")" || exit 1
|
||||
# Finally we use pwd -P to print the absolute path of the directory of $dst.
|
||||
pwd -P || exit 1
|
||||
}
|
||||
|
||||
BIN_DIR=$(bin_dir)
|
||||
exec "$BIN_DIR/../lib/node" "$BIN_DIR/.." "$@"
|
||||
17
ci/build/nfpm.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
name: "code-server"
|
||||
arch: "${ARCH}"
|
||||
platform: "linux"
|
||||
version: "v${VERSION}"
|
||||
section: "devel"
|
||||
priority: "optional"
|
||||
maintainer: "Anmol Sethi <hi@nhooyr.io>"
|
||||
description: |
|
||||
Run VS Code in the browser.
|
||||
vendor: "Coder"
|
||||
homepage: "https://github.com/cdr/code-server"
|
||||
license: "MIT"
|
||||
bindir: "/usr/bin"
|
||||
files:
|
||||
./ci/build/code-server-nfpm.sh: /usr/bin/code-server
|
||||
./ci/build/code-server.service: /usr/lib/systemd/user/code-server.service
|
||||
./release-static/**/*: "/usr/lib/code-server/"
|
||||
47
ci/build/npm-postinstall.sh
Executable file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env sh
|
||||
set -eu
|
||||
|
||||
main() {
|
||||
# Grabs the major version of node from $npm_config_user_agent which looks like
|
||||
# yarn/1.21.1 npm/? node/v14.2.0 darwin x64
|
||||
major_node_version=$(echo "$npm_config_user_agent" | sed -n 's/.*node\/v\([^.]*\).*/\1/p')
|
||||
if [ "$major_node_version" -lt 12 ]; then
|
||||
echo "code-server currently requires at least node v12"
|
||||
echo "We have detected that you are on node v$major_node_version"
|
||||
echo "See https://github.com/cdr/code-server/issues/1633"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "${npm_config_user_agent-}" in npm*)
|
||||
# We are running under npm.
|
||||
if [ "${npm_config_unsafe_perm-}" != "true" ]; then
|
||||
echo "Please pass --unsafe-perm to npm to install code-server"
|
||||
echo "Otherwise the postinstall script does not have permissions to run"
|
||||
echo "See https://docs.npmjs.com/misc/config#unsafe-perm"
|
||||
echo "See https://stackoverflow.com/questions/49084929/npm-sudo-global-installation-unsafe-perm"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
cd lib/vscode
|
||||
|
||||
# We have to rename node_modules.bundled to node_modules.
|
||||
# The bundled modules were renamed originally to avoid being ignored by yarn.
|
||||
node_modules="$(find . -depth -name "node_modules.bundled")"
|
||||
for nm in $node_modules; do
|
||||
rm -Rf "${nm%.bundled}"
|
||||
mv "$nm" "${nm%.bundled}"
|
||||
done
|
||||
|
||||
# $npm_config_global makes npm rebuild return without rebuilding.
|
||||
unset npm_config_global
|
||||
# Rebuilds native modules.
|
||||
if ! npm rebuild; then
|
||||
echo "You may not have the required dependencies to build the native modules."
|
||||
echo "Please see https://github.com/cdr/code-server/blob/master/doc/npm.md"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
21
ci/build/release-github-assets.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Downloads the release artifacts from CI for the current
|
||||
# commit and then uploads them to the release with the version
|
||||
# in package.json.
|
||||
# You will need $GITHUB_TOKEN set.
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
source ./ci/lib.sh
|
||||
|
||||
download_artifact release-packages ./release-packages
|
||||
local assets=(./release-packages/*)
|
||||
for i in "${!assets[@]}"; do
|
||||
assets[$i]="--attach=${assets[$i]}"
|
||||
done
|
||||
EDITOR=true hub release edit --draft "${assets[@]}" "v$VERSION"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
21
ci/build/release-github-draft.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Creates a draft release with the template for the version in package.json
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
source ./ci/lib.sh
|
||||
|
||||
hub release create \
|
||||
--file - \
|
||||
--draft "${assets[@]}" "v$VERSION" << EOF
|
||||
v$VERSION
|
||||
|
||||
VS Code v$(vscode_version)
|
||||
|
||||
- Summarize changes here with references to issues
|
||||
EOF
|
||||
}
|
||||
|
||||
main "$@"
|
||||
27
ci/build/test-static-release.sh
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Makes sure the release works.
|
||||
# This is to make sure we don't have Node version errors or any other
|
||||
# compilation-related errors.
|
||||
main() {
|
||||
cd "$(dirname "${0}")/../.."
|
||||
|
||||
local EXTENSIONS_DIR
|
||||
EXTENSIONS_DIR="$(mktemp -d)"
|
||||
|
||||
echo "Testing static release"
|
||||
|
||||
./release-static/bin/code-server --extensions-dir "$EXTENSIONS_DIR" --install-extension ms-python.python
|
||||
local installed_extensions
|
||||
installed_extensions="$(./release-static/bin/code-server --extensions-dir "$EXTENSIONS_DIR" --list-extensions 2>&1)"
|
||||
if [[ $installed_extensions != "ms-python.python" ]]; then
|
||||
echo "Unexpected output from listing extensions:"
|
||||
echo "$installed_extensions"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Static release works correctly"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
43
ci/container/Dockerfile
Normal file
@@ -0,0 +1,43 @@
|
||||
FROM debian
|
||||
|
||||
RUN apt-get update
|
||||
|
||||
# Needed for debian repositories added below.
|
||||
RUN apt-get install -y curl gnupg
|
||||
|
||||
# Installs node.
|
||||
RUN curl -sSL https://deb.nodesource.com/setup_14.x | bash - && \
|
||||
apt-get install -y nodejs
|
||||
|
||||
# Installs yarn.
|
||||
RUN curl -sSL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
|
||||
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
|
||||
apt-get update && apt-get install -y yarn
|
||||
|
||||
# Installs VS Code build deps.
|
||||
RUN apt-get install -y build-essential \
|
||||
libsecret-1-dev \
|
||||
libx11-dev \
|
||||
libxkbfile-dev
|
||||
|
||||
# Installs envsubst.
|
||||
RUN apt-get install -y gettext-base
|
||||
|
||||
# Misc build dependencies.
|
||||
RUN apt-get install -y jq git rsync
|
||||
|
||||
# Installs shellcheck.
|
||||
RUN curl -sSL https://github.com/koalaman/shellcheck/releases/download/v0.7.1/shellcheck-v0.7.1.linux.$(uname -m).tar.xz | \
|
||||
tar -xJ && \
|
||||
mv shellcheck*/shellcheck /usr/local/bin && \
|
||||
rm -R shellcheck*
|
||||
|
||||
# Install Go dependencies
|
||||
RUN ARCH="$(dpkg --print-architecture)" && \
|
||||
curl -sSL "https://dl.google.com/go/go1.14.3.linux-$ARCH.tar.gz" | tar -C /usr/local -xz
|
||||
ENV PATH=/usr/local/go/bin:/root/go/bin:$PATH
|
||||
ENV GO111MODULE=on
|
||||
RUN go get mvdan.cc/sh/v3/cmd/shfmt
|
||||
RUN go get github.com/goreleaser/nfpm/cmd/nfpm
|
||||
|
||||
RUN curl -fsSL https://get.docker.com | sh
|
||||
12
ci/dev/ci.sh
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
|
||||
yarn fmt
|
||||
yarn lint
|
||||
yarn test
|
||||
}
|
||||
|
||||
main "$@"
|
||||
13
ci/dev/container/Dockerfile
Normal file
@@ -0,0 +1,13 @@
|
||||
FROM node:12
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
iproute2 \
|
||||
vim \
|
||||
iptables \
|
||||
net-tools \
|
||||
libsecret-1-dev \
|
||||
libx11-dev \
|
||||
libxkbfile-dev
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
48
ci/dev/container/exec.sh
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Opens an interactive bash session inside of a docker container
|
||||
# for improved isolation during development.
|
||||
# If the container exists it is restarted if necessary, then reused.
|
||||
|
||||
main() {
|
||||
cd "$(dirname "${0}")/../../.."
|
||||
|
||||
local container_name=code-server-dev
|
||||
|
||||
if docker inspect $container_name &> /dev/null; then
|
||||
echo "-- Starting container"
|
||||
docker start "$container_name" > /dev/null
|
||||
|
||||
enter
|
||||
exit 0
|
||||
fi
|
||||
|
||||
build
|
||||
run
|
||||
enter
|
||||
}
|
||||
|
||||
enter() {
|
||||
echo "--- Entering $container_name"
|
||||
docker exec -it "$container_name" /bin/bash
|
||||
}
|
||||
|
||||
run() {
|
||||
echo "--- Spawning $container_name"
|
||||
docker run \
|
||||
-it \
|
||||
--name $container_name \
|
||||
"-v=$PWD:/code-server" \
|
||||
"-w=/code-server" \
|
||||
"-p=127.0.0.1:8080:8080" \
|
||||
$(if [[ -t 0 ]]; then echo -it; fi) \
|
||||
"$container_name"
|
||||
}
|
||||
|
||||
build() {
|
||||
echo "--- Building $container_name"
|
||||
docker build -t $container_name ./ci/dev/container > /dev/null
|
||||
}
|
||||
|
||||
main "$@"
|
||||
12
ci/dev/diff-vscode.sh
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
|
||||
cd ./lib/vscode
|
||||
git add -A
|
||||
git diff HEAD > ../../ci/dev/vscode.patch
|
||||
}
|
||||
|
||||
main "$@"
|
||||
36
ci/dev/fmt.sh
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
|
||||
shfmt -i 2 -w -s -sr $(git ls-files "*.sh")
|
||||
|
||||
local prettierExts
|
||||
prettierExts=(
|
||||
"*.js"
|
||||
"*.ts"
|
||||
"*.tsx"
|
||||
"*.html"
|
||||
"*.json"
|
||||
"*.css"
|
||||
"*.md"
|
||||
"*.toml"
|
||||
"*.yaml"
|
||||
"*.yml"
|
||||
)
|
||||
prettier --write --loglevel=warn $(git ls-files "${prettierExts[@]}")
|
||||
|
||||
doctoc --title '# FAQ' doc/FAQ.md > /dev/null
|
||||
doctoc --title '# Setup Guide' doc/guide.md > /dev/null
|
||||
|
||||
if [[ ${CI-} && $(git ls-files --other --modified --exclude-standard) ]]; then
|
||||
echo "Files need generation or are formatted incorrectly:"
|
||||
git -c color.ui=always status | grep --color=no '\[31m'
|
||||
echo "Please run the following locally:"
|
||||
echo " yarn fmt"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
13
ci/dev/lint.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
|
||||
eslint --max-warnings=0 --fix $(git ls-files "*.ts" "*.tsx" "*.js")
|
||||
stylelint $(git ls-files "*.css")
|
||||
tsc --noEmit
|
||||
shellcheck -e SC2046,SC2164,SC2154 $(git ls-files "*.sh")
|
||||
}
|
||||
|
||||
main "$@"
|
||||
11
ci/dev/patch-vscode.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
|
||||
cd ./lib/vscode
|
||||
git apply ../../ci/dev/vscode.patch
|
||||
}
|
||||
|
||||
main "$@"
|
||||
10
ci/dev/test.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
|
||||
mocha -r ts-node/register ./test/*.test.ts
|
||||
}
|
||||
|
||||
main "$@"
|
||||
3535
ci/dev/vscode.patch
Normal file
22
ci/dev/vscode.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# 1. Ensures VS Code is cloned.
|
||||
# 2. Patches it.
|
||||
# 3. Installs it.
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
|
||||
git submodule update --init
|
||||
|
||||
# If the patch fails to apply, then it's likely already applied
|
||||
yarn vscode:patch &> /dev/null || true
|
||||
|
||||
(
|
||||
cd lib/vscode
|
||||
# Install VS Code dependencies.
|
||||
yarn ${CI+--frozen-lockfile}
|
||||
)
|
||||
}
|
||||
|
||||
main "$@"
|
||||
163
ci/dev/watch.ts
Normal file
@@ -0,0 +1,163 @@
|
||||
import * as cp from "child_process"
|
||||
import Bundler from "parcel-bundler"
|
||||
import * as path from "path"
|
||||
|
||||
async function main(): Promise<void> {
|
||||
try {
|
||||
const watcher = new Watcher()
|
||||
await watcher.watch()
|
||||
} catch (error) {
|
||||
console.error(error.message)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
class Watcher {
|
||||
private readonly rootPath = path.resolve(__dirname, "../..")
|
||||
private readonly vscodeSourcePath = path.join(this.rootPath, "lib/vscode")
|
||||
|
||||
private static log(message: string, skipNewline = false): void {
|
||||
process.stdout.write(message)
|
||||
if (!skipNewline) {
|
||||
process.stdout.write("\n")
|
||||
}
|
||||
}
|
||||
|
||||
public async watch(): Promise<void> {
|
||||
let server: cp.ChildProcess | undefined
|
||||
const restartServer = (): void => {
|
||||
if (server) {
|
||||
server.kill()
|
||||
}
|
||||
const s = cp.fork(path.join(this.rootPath, "out/node/entry.js"), process.argv.slice(2))
|
||||
console.log(`[server] spawned process ${s.pid}`)
|
||||
s.on("exit", () => console.log(`[server] process ${s.pid} exited`))
|
||||
server = s
|
||||
}
|
||||
|
||||
const vscode = cp.spawn("yarn", ["watch"], { cwd: this.vscodeSourcePath })
|
||||
const tsc = cp.spawn("tsc", ["--watch", "--pretty", "--preserveWatchOutput"], { cwd: this.rootPath })
|
||||
const bundler = this.createBundler()
|
||||
|
||||
const cleanup = (code?: number | null): void => {
|
||||
Watcher.log("killing vs code watcher")
|
||||
vscode.removeAllListeners()
|
||||
vscode.kill()
|
||||
|
||||
Watcher.log("killing tsc")
|
||||
tsc.removeAllListeners()
|
||||
tsc.kill()
|
||||
|
||||
if (server) {
|
||||
Watcher.log("killing server")
|
||||
server.removeAllListeners()
|
||||
server.kill()
|
||||
}
|
||||
|
||||
Watcher.log("killing bundler")
|
||||
process.exit(code || 0)
|
||||
}
|
||||
|
||||
process.on("SIGINT", () => cleanup())
|
||||
process.on("SIGTERM", () => cleanup())
|
||||
|
||||
vscode.on("exit", (code) => {
|
||||
Watcher.log("vs code watcher terminated unexpectedly")
|
||||
cleanup(code)
|
||||
})
|
||||
tsc.on("exit", (code) => {
|
||||
Watcher.log("tsc terminated unexpectedly")
|
||||
cleanup(code)
|
||||
})
|
||||
const bundle = bundler.bundle().catch(() => {
|
||||
Watcher.log("parcel watcher terminated unexpectedly")
|
||||
cleanup(1)
|
||||
})
|
||||
bundler.on("buildEnd", () => {
|
||||
console.log("[parcel] bundled")
|
||||
})
|
||||
bundler.on("buildError", (error) => {
|
||||
console.error("[parcel]", error)
|
||||
})
|
||||
|
||||
vscode.stderr.on("data", (d) => process.stderr.write(d))
|
||||
tsc.stderr.on("data", (d) => process.stderr.write(d))
|
||||
|
||||
// From https://github.com/chalk/ansi-regex
|
||||
const pattern = [
|
||||
"[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
|
||||
"(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))",
|
||||
].join("|")
|
||||
const re = new RegExp(pattern, "g")
|
||||
|
||||
/**
|
||||
* Split stdout on newlines and strip ANSI codes.
|
||||
*/
|
||||
const onLine = (proc: cp.ChildProcess, callback: (strippedLine: string, originalLine: string) => void): void => {
|
||||
let buffer = ""
|
||||
if (!proc.stdout) {
|
||||
throw new Error("no stdout")
|
||||
}
|
||||
proc.stdout.setEncoding("utf8")
|
||||
proc.stdout.on("data", (d) => {
|
||||
const data = buffer + d
|
||||
const split = data.split("\n")
|
||||
const last = split.length - 1
|
||||
|
||||
for (let i = 0; i < last; ++i) {
|
||||
callback(split[i].replace(re, ""), split[i])
|
||||
}
|
||||
|
||||
// The last item will either be an empty string (the data ended with a
|
||||
// newline) or a partial line (did not end with a newline) and we must
|
||||
// wait to parse it until we get a full line.
|
||||
buffer = split[last]
|
||||
})
|
||||
}
|
||||
|
||||
let startingVscode = false
|
||||
let startedVscode = false
|
||||
onLine(vscode, (line, original) => {
|
||||
console.log("[vscode]", original)
|
||||
// Wait for watch-client since "Finished compilation" will appear multiple
|
||||
// times before the client starts building.
|
||||
if (!startingVscode && line.includes("Starting watch-client")) {
|
||||
startingVscode = true
|
||||
} else if (startingVscode && line.includes("Finished compilation")) {
|
||||
if (startedVscode) {
|
||||
bundle.then(restartServer)
|
||||
}
|
||||
startedVscode = true
|
||||
}
|
||||
})
|
||||
|
||||
onLine(tsc, (line, original) => {
|
||||
// tsc outputs blank lines; skip them.
|
||||
if (line !== "") {
|
||||
console.log("[tsc]", original)
|
||||
}
|
||||
if (line.includes("Watching for file changes")) {
|
||||
bundle.then(restartServer)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private createBundler(out = "dist"): Bundler {
|
||||
return new Bundler(
|
||||
[
|
||||
path.join(this.rootPath, "src/browser/pages/app.ts"),
|
||||
path.join(this.rootPath, "src/browser/register.ts"),
|
||||
path.join(this.rootPath, "src/browser/serviceWorker.ts"),
|
||||
],
|
||||
{
|
||||
outDir: path.join(this.rootPath, out),
|
||||
cacheDir: path.join(this.rootPath, ".cache"),
|
||||
minify: !!process.env.MINIFY,
|
||||
logLevel: 1,
|
||||
publicUrl: "/static/development/dist",
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
95
ci/lib.sh
Executable file
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
pushd() {
|
||||
builtin pushd "$@" > /dev/null
|
||||
}
|
||||
|
||||
popd() {
|
||||
builtin popd > /dev/null
|
||||
}
|
||||
|
||||
pkg_json_version() {
|
||||
jq -r .version package.json
|
||||
}
|
||||
|
||||
vscode_version() {
|
||||
jq -r .version lib/vscode/package.json
|
||||
}
|
||||
|
||||
os() {
|
||||
local os
|
||||
os=$(uname | tr '[:upper:]' '[:lower:]')
|
||||
if [[ $os == "linux" ]]; then
|
||||
# Alpine's ldd doesn't have a version flag but if you use an invalid flag
|
||||
# (like --version) it outputs the version to stderr and exits with 1.
|
||||
local ldd_output
|
||||
ldd_output=$(ldd --version 2>&1 || true)
|
||||
if echo "$ldd_output" | grep -iq musl; then
|
||||
os="alpine"
|
||||
fi
|
||||
elif [[ $os == "darwin" ]]; then
|
||||
os="macos"
|
||||
fi
|
||||
echo "$os"
|
||||
}
|
||||
|
||||
arch() {
|
||||
case "$(uname -m)" in
|
||||
aarch64)
|
||||
echo arm64
|
||||
;;
|
||||
x86_64)
|
||||
echo amd64
|
||||
;;
|
||||
*)
|
||||
echo "unknown architecture $(uname -a)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
curl() {
|
||||
command curl -H "Authorization: token $GITHUB_TOKEN" "$@"
|
||||
}
|
||||
|
||||
# Grabs the most recent ci.yaml github workflow run that was successful and triggered from the same commit being pushd.
|
||||
# This will contain the artifacts we want.
|
||||
# https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs
|
||||
get_artifacts_url() {
|
||||
curl -sSL 'https://api.github.com/repos/cdr/code-server/actions/workflows/ci.yaml/runs?status=success&event=push' | jq -r ".workflow_runs[] | select(.head_sha == \"$(git rev-parse HEAD)\") | .artifacts_url" | head -n 1
|
||||
}
|
||||
|
||||
# Grabs the artifact's download url.
|
||||
# https://developer.github.com/v3/actions/artifacts/#list-workflow-run-artifacts
|
||||
get_artifact_url() {
|
||||
local artifact_name="$1"
|
||||
curl -sSL "$(get_artifacts_url)" | jq -r ".artifacts[] | select(.name == \"$artifact_name\") | .archive_download_url" | head -n 1
|
||||
}
|
||||
|
||||
# Uses the above two functions to download a artifact into a directory.
|
||||
download_artifact() {
|
||||
local artifact_name="$1"
|
||||
local dst="$2"
|
||||
|
||||
local tmp_file
|
||||
tmp_file="$(mktemp)"
|
||||
|
||||
curl -sSL "$(get_artifact_url "$artifact_name")" > "$tmp_file"
|
||||
unzip -q -o "$tmp_file" -d "$dst"
|
||||
rm "$tmp_file"
|
||||
}
|
||||
|
||||
rsync() {
|
||||
command rsync -a --del "$@"
|
||||
}
|
||||
|
||||
VERSION="$(pkg_json_version)"
|
||||
export VERSION
|
||||
ARCH="$(arch)"
|
||||
export ARCH
|
||||
OS=$(os)
|
||||
export OS
|
||||
|
||||
# RELEASE_PATH is the destination directory for the release from the root.
|
||||
# Defaults to release
|
||||
RELEASE_PATH="${RELEASE_PATH-release}"
|
||||
43
ci/release-container/Dockerfile
Normal file
@@ -0,0 +1,43 @@
|
||||
FROM debian:10
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y \
|
||||
curl \
|
||||
dumb-init \
|
||||
htop \
|
||||
locales \
|
||||
man \
|
||||
nano \
|
||||
git \
|
||||
procps \
|
||||
ssh \
|
||||
sudo \
|
||||
vim \
|
||||
lsb-release \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# https://wiki.debian.org/Locale#Manually
|
||||
RUN sed -i "s/# en_US.UTF-8/en_US.UTF-8/" /etc/locale.gen \
|
||||
&& locale-gen
|
||||
ENV LANG=en_US.UTF-8
|
||||
|
||||
RUN chsh -s /bin/bash
|
||||
ENV SHELL=/bin/bash
|
||||
|
||||
RUN adduser --gecos '' --disabled-password coder && \
|
||||
echo "coder ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/nopasswd
|
||||
|
||||
RUN ARCH="$(dpkg --print-architecture)" && \
|
||||
curl -sSL "https://github.com/boxboat/fixuid/releases/download/v0.4.1/fixuid-0.4.1-linux-$ARCH.tar.gz" | tar -C /usr/local/bin -xzf - && \
|
||||
chown root:root /usr/local/bin/fixuid && \
|
||||
chmod 4755 /usr/local/bin/fixuid && \
|
||||
mkdir -p /etc/fixuid && \
|
||||
printf "user: coder\ngroup: coder\n" > /etc/fixuid/config.yml
|
||||
|
||||
COPY release-packages/code-server*.deb /tmp/
|
||||
RUN dpkg -i /tmp/code-server*$(dpkg --print-architecture).deb && rm /tmp/code-server*.deb
|
||||
|
||||
EXPOSE 8080
|
||||
USER coder
|
||||
WORKDIR /home/coder
|
||||
ENTRYPOINT ["dumb-init", "fixuid", "-q", "/usr/bin/code-server", "--bind-addr", "0.0.0.0:8080", "."]
|
||||
11
ci/release-container/build.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
source ./ci/lib.sh
|
||||
|
||||
docker build -t "codercom/code-server-$ARCH:$VERSION" -f ./ci/release-container/Dockerfile .
|
||||
}
|
||||
|
||||
main "$@"
|
||||
14
ci/steps/build-docker-image.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
source ./ci/lib.sh
|
||||
|
||||
./ci/release-container/build.sh
|
||||
|
||||
mkdir -p release-images
|
||||
docker save "codercom/code-server-$ARCH:$VERSION" > "release-images/code-server-$ARCH-$VERSION.tar"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
17
ci/steps/fmt.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
|
||||
yarn --frozen-lockfile
|
||||
|
||||
git submodule update --init
|
||||
# We do not `yarn vscode` to make test.sh faster.
|
||||
# If the patch fails to apply, then it's likely already applied
|
||||
yarn vscode:patch &> /dev/null || true
|
||||
|
||||
yarn fmt
|
||||
}
|
||||
|
||||
main "$@"
|
||||
17
ci/steps/lint.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
|
||||
yarn --frozen-lockfile
|
||||
|
||||
git submodule update --init
|
||||
# We do not `yarn vscode` to make test.sh faster.
|
||||
# If the patch fails to apply, then it's likely already applied
|
||||
yarn vscode:patch &> /dev/null || true
|
||||
|
||||
yarn lint
|
||||
}
|
||||
|
||||
main "$@"
|
||||
18
ci/steps/publish-npm.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
source ./ci/lib.sh
|
||||
|
||||
if [[ ${CI-} ]]; then
|
||||
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
|
||||
fi
|
||||
|
||||
download_artifact npm-package ./release
|
||||
# https://github.com/actions/upload-artifact/issues/38
|
||||
chmod +x $(grep -rl '^#!/.*' release)
|
||||
yarn publish --non-interactive release
|
||||
}
|
||||
|
||||
main "$@"
|
||||
37
ci/steps/push-docker-manifest.sh
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
source ./ci/lib.sh
|
||||
|
||||
download_artifact release-images ./release-images
|
||||
if [[ ${CI-} ]]; then
|
||||
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
|
||||
fi
|
||||
|
||||
for img in ./release-images/*; do
|
||||
docker load -i "$img"
|
||||
done
|
||||
|
||||
# We have to ensure the amd64 and arm64 images exist on the remote registry
|
||||
# in order to build the manifest.
|
||||
# We don't put the arch in the tag to avoid polluting the main repository.
|
||||
# These other repositories are private so they don't pollute our organization namespace.
|
||||
docker push "codercom/code-server-amd64:$VERSION"
|
||||
docker push "codercom/code-server-arm64:$VERSION"
|
||||
|
||||
export DOCKER_CLI_EXPERIMENTAL=enabled
|
||||
|
||||
docker manifest create "codercom/code-server:$VERSION" \
|
||||
"codercom/code-server-amd64:$VERSION" \
|
||||
"codercom/code-server-arm64:$VERSION"
|
||||
docker manifest push --purge "codercom/code-server:$VERSION"
|
||||
|
||||
docker manifest create "codercom/code-server:latest" \
|
||||
"codercom/code-server-amd64:$VERSION" \
|
||||
"codercom/code-server-arm64:$VERSION"
|
||||
docker manifest push --purge "codercom/code-server:latest"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
15
ci/steps/release-static.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
|
||||
# https://github.com/actions/upload-artifact/issues/38
|
||||
chmod +x $(grep -rl '^#!/.*' release)
|
||||
|
||||
yarn release:static
|
||||
yarn test:static-release
|
||||
yarn package
|
||||
}
|
||||
|
||||
main "$@"
|
||||
14
ci/steps/release.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
|
||||
yarn --frozen-lockfile
|
||||
yarn vscode
|
||||
yarn build
|
||||
yarn build:vscode
|
||||
yarn release
|
||||
}
|
||||
|
||||
main "$@"
|
||||
17
ci/steps/test.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
main() {
|
||||
cd "$(dirname "$0")/../.."
|
||||
|
||||
yarn --frozen-lockfile
|
||||
|
||||
git submodule update --init
|
||||
# We do not `yarn vscode` to make test.sh faster.
|
||||
# If the patch fails to apply, then it's likely already applied
|
||||
yarn vscode:patch &> /dev/null || true
|
||||
|
||||
yarn test
|
||||
}
|
||||
|
||||
main "$@"
|
||||
117
doc/CONTRIBUTING.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# Contributing
|
||||
|
||||
- [Detailed CI and build process docs](../ci)
|
||||
|
||||
## Requirements
|
||||
|
||||
Please refer to [VS Code's prerequisites](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#prerequisites).
|
||||
|
||||
Differences:
|
||||
|
||||
- We require a minimum of node v12 but later versions should work.
|
||||
- We use [fnpm](https://github.com/goreleaser/nfpm) to build `.deb` and `.rpm` packages.
|
||||
- The [CI container](../ci/container/Dockerfile) is a useful reference for all our dependencies.
|
||||
|
||||
## Development Workflow
|
||||
|
||||
```shell
|
||||
yarn
|
||||
yarn vscode
|
||||
yarn watch
|
||||
# Visit http://localhost:8080 once the build completed.
|
||||
```
|
||||
|
||||
To develop inside of an isolated docker container:
|
||||
|
||||
```shell
|
||||
./ci/dev/container/exec.sh
|
||||
|
||||
root@12345:/code-server# yarn
|
||||
root@12345:/code-server# yarn vscode
|
||||
root@12345:/code-server# yarn watch
|
||||
```
|
||||
|
||||
Any changes made to the source will be live reloaded.
|
||||
|
||||
If changes are made to the patch and you've built previously you must manually
|
||||
reset VS Code then run `yarn vscode:patch`.
|
||||
|
||||
## Build
|
||||
|
||||
```shell
|
||||
yarn
|
||||
yarn vscode
|
||||
yarn build
|
||||
yarn build:vscode
|
||||
yarn release
|
||||
cd release
|
||||
yarn --production
|
||||
# Runs the built JavaScript with Node.
|
||||
node .
|
||||
```
|
||||
|
||||
Now you can make it static and build packages with:
|
||||
|
||||
```
|
||||
yarn release:static
|
||||
yarn test:static-release
|
||||
yarn package
|
||||
# The static release is in ./release-static
|
||||
# .deb, .rpm and the static archive are in ./release-packages
|
||||
```
|
||||
|
||||
## Structure
|
||||
|
||||
The `code-server` script serves an HTTP API to login and start a remote VS Code process.
|
||||
|
||||
The CLI code is in [./src/node](./src/node) and the HTTP routes are implemented in
|
||||
[./src/node/app](./src/node/app).
|
||||
|
||||
Most of the meaty parts are in our VS Code patch which is described next.
|
||||
|
||||
### VS Code Patch
|
||||
|
||||
Back in v1 of code-server, we had an extensive patch of VS Code that split the codebase
|
||||
into a frontend and server. The frontend consisted of all UI code and the server ran
|
||||
the extensions and exposed an API to the frontend for file access and everything else
|
||||
that the UI needed.
|
||||
|
||||
This worked but eventually Microsoft added support to VS Code to run it in the web.
|
||||
They have open sourced the frontend but have kept the server closed source.
|
||||
|
||||
So in interest of piggy backing off their work, v2 and beyond use the VS Code
|
||||
web frontend and fill in the server. This is contained in our
|
||||
[./ci/dev/vscode.patch](../ci/dev/vscode.patch) under the path `src/vs/server`.
|
||||
|
||||
Other notable changes in our patch include:
|
||||
|
||||
- Add our own build file which includes our code and VS Code's web code.
|
||||
- Allow multiple extension directories (both user and built-in).
|
||||
- Modify the loader, websocket, webview, service worker, and asset requests to
|
||||
use the URL of the page as a base (and TLS if necessary for the websocket).
|
||||
- Send client-side telemetry through the server.
|
||||
- Allow modification of the display language.
|
||||
- Make it possible for us to load code on the client.
|
||||
- Make extensions work in the browser.
|
||||
- Make it possible to install extensions of any kind.
|
||||
- Fix getting permanently disconnected when you sleep or hibernate for a while.
|
||||
- Add connection type to web socket query parameters.
|
||||
|
||||
Some known issues presently:
|
||||
|
||||
- Creating custom VS Code extensions and debugging them doesn't work.
|
||||
- Extension profiling and tips are currently disabled.
|
||||
|
||||
As the web portion of VS Code matures, we'll be able to shrink and maybe even entirely
|
||||
eliminate our patch. In the meantime, however, upgrading the VS Code version requires
|
||||
ensuring that the patch still applies and has the intended effects.
|
||||
|
||||
To generate a new patch run `yarn vscode:diff`.
|
||||
|
||||
**note**: We have extension docs on the CI and build system at [./ci/README.md](../ci/README.md)
|
||||
|
||||
If functionality doesn't depend on code from VS Code then it should be moved
|
||||
into code-server otherwise it should be in the patch.
|
||||
|
||||
In the future we'd like to run VS Code unit tests against our builds to ensure features
|
||||
work as expected.
|
||||
235
doc/FAQ.md
Normal file
@@ -0,0 +1,235 @@
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
# FAQ
|
||||
|
||||
- [Questions?](#questions)
|
||||
- [What's the deal with extensions?](#whats-the-deal-with-extensions)
|
||||
- [Where are extensions stored?](#where-are-extensions-stored)
|
||||
- [How is this different from VS Code Codespaces?](#how-is-this-different-from-vs-code-codespaces)
|
||||
- [How should I expose code-server to the internet?](#how-should-i-expose-code-server-to-the-internet)
|
||||
- [How do I securely access web services?](#how-do-i-securely-access-web-services)
|
||||
- [Sub-domains](#sub-domains)
|
||||
- [Sub-paths](#sub-paths)
|
||||
- [Multi-tenancy](#multi-tenancy)
|
||||
- [Docker in code-server docker container?](#docker-in-code-server-docker-container)
|
||||
- [Collaboration](#collaboration)
|
||||
- [How can I disable telemetry?](#how-can-i-disable-telemetry)
|
||||
- [How does code-server decide what workspace or folder to open?](#how-does-code-server-decide-what-workspace-or-folder-to-open)
|
||||
- [How do I debug issues with code-server?](#how-do-i-debug-issues-with-code-server)
|
||||
- [Heartbeat file](#heartbeat-file)
|
||||
- [How does the config file work?](#how-does-the-config-file-work)
|
||||
- [Enterprise](#enterprise)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
## Questions?
|
||||
|
||||
Please file all questions and support requests at https://www.reddit.com/r/codeserver/.
|
||||
|
||||
The issue tracker is **only** for bugs.
|
||||
|
||||
## What's the deal with extensions?
|
||||
|
||||
Unfortunately, the Microsoft VS Code Marketplace license prohibits use with any non Microsoft
|
||||
product.
|
||||
|
||||
See https://cdn.vsassets.io/v/M146_20190123.39/_content/Microsoft-Visual-Studio-Marketplace-Terms-of-Use.pdf
|
||||
|
||||
> Marketplace Offerings are intended for use only with Visual Studio Products and Services
|
||||
> and you may only install and use Marketplace Offerings with Visual Studio Products and Services.
|
||||
|
||||
As a result, Coder has created its own marketplace for open source extensions. It works by scraping
|
||||
GitHub for VS Code extensions and building them. It's not perfect but getting better by the day with
|
||||
more and more extensions.
|
||||
|
||||
Issue [#1299](https://github.com/cdr/code-server/issues/1299) is a big one in making the experience here
|
||||
better by allowing the community to submit extensions and repos to avoid waiting until the scraper finds
|
||||
an extension.
|
||||
|
||||
If an extension is not available or does not work, you can grab its VSIX from its Github releases or
|
||||
build it yourself. Then run the `Extensions: Install from VSIX` command in the Command Palette and
|
||||
point to the .vsix file.
|
||||
|
||||
See below for installing an extension from the cli.
|
||||
|
||||
Feel free to file an issue to add a missing extension to the marketplace.
|
||||
|
||||
If you have your own custom marketplace, it is possible to point code-server to it by setting
|
||||
`$SERVICE_URL` and `$ITEM_URL` to point to it.
|
||||
|
||||
## Where are extensions stored?
|
||||
|
||||
Defaults to `~/.local/share/code-server/extensions`.
|
||||
|
||||
If the `XDG_DATA_HOME` environment variable is set the data directory will be
|
||||
`$XDG_DATA_HOME/code-server/extensions`. In general we try to follow the XDG directory spec.
|
||||
|
||||
You can install an extension on the CLI with:
|
||||
|
||||
```bash
|
||||
# From the Coder extension marketplace
|
||||
code-server --install-extension ms-python.python
|
||||
|
||||
# From a downloaded VSIX on the file system
|
||||
code-server --install-extension downloaded-ms-python.python.vsix
|
||||
```
|
||||
|
||||
## How is this different from VS Code Codespaces?
|
||||
|
||||
VS Code Codespaces is a closed source and paid service by Microsoft. It also allows you to access
|
||||
VS Code via the browser.
|
||||
|
||||
However, code-server is free, open source and can be ran on any machine without any limitations.
|
||||
|
||||
While you can self host environments with VS Code Codespaces, you still need to an Azure billing
|
||||
account and you access VS Code via the Codespaces web dashboard instead of directly connecting to
|
||||
your instance.
|
||||
|
||||
## How should I expose code-server to the internet?
|
||||
|
||||
Please follow [./guide.md](./guide.md) for our recommendations on setting up and using code-server.
|
||||
|
||||
code-server only supports password authentication natively.
|
||||
|
||||
**note**: code-server will rate limit password authentication attempts at 2 a minute and 12 an hour.
|
||||
|
||||
If you want to use external authentication (i.e sign in with Google) you should handle this
|
||||
with a reverse proxy using something like [oauth2_proxy](https://github.com/pusher/oauth2_proxy).
|
||||
|
||||
For HTTPS, you can use a self signed certificate by passing in just `--cert` or
|
||||
pass in an existing certificate by providing the path to `--cert` and the path to
|
||||
its key with `--cert-key`.
|
||||
|
||||
If `code-server` has been passed a certificate it will also respond to HTTPS
|
||||
requests and will redirect all HTTP requests to HTTPS. Otherwise it will respond
|
||||
only to HTTP requests.
|
||||
|
||||
You can use [Let's Encrypt](https://letsencrypt.org/) to get an SSL certificate
|
||||
for free.
|
||||
|
||||
Again, Please follow [./guide.md](./guide.md) for our recommendations on setting up and using code-server.
|
||||
|
||||
## How do I securely access web services?
|
||||
|
||||
code-server is capable of proxying to any port using either a subdomain or a
|
||||
subpath which means you can securely access these services using code-server's
|
||||
built-in authentication.
|
||||
|
||||
### Sub-domains
|
||||
|
||||
You will need a DNS entry that points to your server for each port you want to
|
||||
access. You can either set up a wildcard DNS entry for `*.<domain>` if your domain
|
||||
name registrar supports it or you can create one for every port you want to
|
||||
access (`3000.<domain>`, `8080.<domain>`, etc).
|
||||
|
||||
You should also set up TLS certificates for these subdomains, either using a
|
||||
wildcard certificate for `*.<domain>` or individual certificates for each port.
|
||||
|
||||
Start code-server with the `--proxy-domain` flag set to your domain.
|
||||
|
||||
```
|
||||
code-server --proxy-domain <domain>
|
||||
```
|
||||
|
||||
Now you can browse to `<port>.<domain>`. Note that this uses the host header so
|
||||
ensure your reverse proxy forwards that information if you are using one.
|
||||
|
||||
### Sub-paths
|
||||
|
||||
Just browse to `/proxy/<port>/`.
|
||||
|
||||
## Multi-tenancy
|
||||
|
||||
If you want to run multiple code-server's on shared infrastructure, we recommend using virtual
|
||||
machines with a VM per user. This will easily allow users to run a docker daemon. If you want
|
||||
to use kubernetes, you'll definitely want to use [kubevirt](https://kubevirt.io) to give each
|
||||
user a virtual machine instead of just a container. Docker in docker while supported requires
|
||||
privileged containers which are a security risk in a multi tenant infrastructure.
|
||||
|
||||
## Docker in code-server docker container?
|
||||
|
||||
If you'd like to access docker inside of code-server, we'd recommend running a docker:dind container
|
||||
and mounting in a directory to share between dind and the code-server container at /var/run. After, install
|
||||
the docker CLI in the code-server container and you should be able to access the daemon as the socket
|
||||
will be shared at /var/run/docker.sock.
|
||||
|
||||
In order to make volume mounts work, mount the home directory in the code-server container and the
|
||||
dind container at the same path. i.e you'd volume mount a directory from the host to `/home/coder`
|
||||
on both. This will allow any volume mounts in the home directory to work. Similar process
|
||||
to make volume mounts in any other directory work.
|
||||
|
||||
## Collaboration
|
||||
|
||||
We understand the high demand but the team is swamped right now.
|
||||
|
||||
You can follow progress at [#33](https://github.com/cdr/code-server/issues/33).
|
||||
|
||||
## How can I disable telemetry?
|
||||
|
||||
Use the `--disable-telemetry` flag to completely disable telemetry. We use the
|
||||
data collected only to improve code-server.
|
||||
|
||||
## How does code-server decide what workspace or folder to open?
|
||||
|
||||
code-server tries the following in order:
|
||||
|
||||
1. The `workspace` query parameter.
|
||||
2. The `folder` query parameter.
|
||||
3. The workspace or directory passed on the command line.
|
||||
4. The last opened workspace or directory.
|
||||
|
||||
## How do I debug issues with code-server?
|
||||
|
||||
First run code-server with at least `debug` logging (or `trace` to be really
|
||||
thorough) by setting the `--log` flag or the `LOG_LEVEL` environment variable.
|
||||
`-vvv` and `--verbose` are aliases for `--log trace`.
|
||||
|
||||
```
|
||||
code-server --log debug
|
||||
```
|
||||
|
||||
Once this is done, replicate the issue you're having then collect logging
|
||||
information from the following places:
|
||||
|
||||
1. stdout
|
||||
2. The most recently created directory in the `~/.local/share/code-server/logs` directory
|
||||
3. The browser console and network tabs.
|
||||
|
||||
Additionally, collecting core dumps (you may need to enable them first) if
|
||||
code-server crashes can be helpful.
|
||||
|
||||
## Heartbeat file
|
||||
|
||||
`code-server` touches `~/.local/share/code-server/heartbeat` once a minute as long
|
||||
as there is an active browser connection.
|
||||
|
||||
If you want to shutdown `code-server` if there hasn't been an active connection in X minutes
|
||||
you can do so by continuously checking the last modified time on the heartbeat file and if it is
|
||||
older than X minutes, you should kill `code-server`.
|
||||
|
||||
[#1636](https://github.com/cdr/code-server/issues/1636) will make the experience here better.
|
||||
|
||||
## How does the config file work?
|
||||
|
||||
When `code-server` starts up, it creates a default config file in `~/.config/code-server/config.yaml` that looks
|
||||
like this:
|
||||
|
||||
```yaml
|
||||
bind-addr: 127.0.0.1:8080
|
||||
auth: password
|
||||
password: mewkmdasosafuio3422 # This is randomly generated for each config.yaml
|
||||
cert: false
|
||||
```
|
||||
|
||||
Each key in the file maps directly to a `code-server` flag. Run `code-server --help` to see
|
||||
a listing of all the flags.
|
||||
|
||||
The default config here says to listen on the loopback IP port 8080, enable password authorization
|
||||
and no TLS. Any flags passed to `code-server` will take priority over the config file.
|
||||
|
||||
The `--config` flag or `$CODE_SERVER_CONFIG` can be used to change the config file's location.
|
||||
|
||||
## Enterprise
|
||||
|
||||
Visit [our enterprise page](https://coder.com) for more information about our
|
||||
enterprise offerings.
|
||||
@@ -1,57 +0,0 @@
|
||||
# Deploy on AWS
|
||||
|
||||
This tutorial shows you how to deploy `code-server` on an EC2 AWS instance.
|
||||
|
||||
If you're just starting out, we recommend [installing code-server locally](../../self-hosted/index.md). It takes only a few minutes and lets you try out all of the features. You can also try out the IDE on a container hosted [by Coder](http://coder.com/signup)
|
||||
|
||||
---
|
||||
|
||||
## Deploy to EC2
|
||||
|
||||
### Use the AWS wizard
|
||||
|
||||
- Click **Launch Instance** from your [EC2 dashboard](https://console.aws.amazon.com/ec2/v2/home).
|
||||
- Select the Ubuntu Server 16.04 LTS (HVM), SSD Volume Type (`ami-0f9cf087c1f27d9b1)` at this time of writing)
|
||||
- Select an appropriate instance size (we recommend t2.medium/large, depending on team size and number of repositories/languages enabled), then **Next: Configure Instance Details**
|
||||
- Select **Next: ...** until you get to the **Configure Security Group** page, then add the default **HTTP** rule (port range "80", source "0.0.0.0/0, ::/0")
|
||||
> Rules with source of 0.0.0.0/0 allow all IP addresses to access your instance. We recommend setting [security group rules](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html?icmpid=docs_ec2_console) to allow access from known IP addresses only.
|
||||
- Click **Launch**
|
||||
- You will be prompted to create a key pair
|
||||
> A key pair consists of a public key that AWS stores, and a private key file that you store. Together, they allow you to connect to your instance securely. For Windows AMIs, the private key file is required to obtain the password used to log into your instance. For Linux AMIs, the private key file allows you to securely SSH into your instance.
|
||||
- From the dropdown choose "create a new pair", give the key pair a name
|
||||
- Click **Download Key Pair**
|
||||
> This is necessary before you proceed. A `.pem` file will be downloaded. make sure you store is in a safe location because it can't be retrieved once we move on.
|
||||
- Finally, click **Launch Instances**
|
||||
---
|
||||
### SSH Into EC2 Instance
|
||||
- First head to your [EC2 dashboard](https://console.aws.amazon.com/ec2/v2/home) and choose instances from the left panel
|
||||
- In the description of your EC2 instance copy the public DNS (iPv4) address using the copy to clipboard button
|
||||
- Open a terminal on your computer and use the following command to SSH into your EC2 instance
|
||||
```
|
||||
ssh -i "path/to/your/keypair.pem" ubuntu@(paste the public DNS here)
|
||||
```
|
||||
>example: `ssh -i "/Users/John/Downloads/TestInstance.pem" ubuntu@ec2-3-45-678-910.compute-1.amazonaws.co`
|
||||
- You should see a prompt for your EC2 instance like so<img src="../../assets/aws_ubuntu.png">
|
||||
- At this point it is time to download the `code-server` binary. We will of course want the linux version. Make sure you copy the link for the latest linux version on our [releases page](https://github.com/codercom/code-server/releases)
|
||||
- With the URL in the clipboard, run:
|
||||
```
|
||||
wget https://github.com/codercom/code-server/releases/download/0.1.4/code-server-linux
|
||||
```
|
||||
- If you run into any permission errors, make the binary executable by running:
|
||||
```
|
||||
chmod +x code-server-linux
|
||||
```
|
||||
> To ensure the connection between you and your server is encrypted view our guide on [securing your setup](../security/ssl.md)
|
||||
- Finally, run
|
||||
```
|
||||
sudo ./code-server-linux -p 80
|
||||
```
|
||||
- When you visit the public IP for your AWS instance, you will be greeted with this page. Code-server is using a self-signed SSL certificate for easy setup. To proceed to the IDE, click **"Advanced"**<img src ="../../assets/chrome_warning.png">
|
||||
- Then click **"proceed anyway"**<img src="../../assets/chrome_confirm.png">
|
||||
|
||||
> For instructions on how to keep the server running after you end your SSH session please checkout [how to use systemd](https://www.linode.com/docs/quick-answers/linux/start-service-at-boot/) to start linux based services if they are killed
|
||||
|
||||
> The `-p 80` flag is necessary in order to make the IDE accessible from the public IP of your instance (also available from the description in the instances page.
|
||||
|
||||
---
|
||||
> NOTE: If you get stuck or need help, [file an issue](https://github.com/codercom/code-server/issues/new?&title=Improve+self-hosted+quickstart+guide), [tweet (@coderhq)](https://twitter.com/coderhq) or [email](mailto:support@coder.com?subject=Self-hosted%20quickstart%20guide).
|
||||
@@ -1,37 +0,0 @@
|
||||
# Deploy on DigitalOcean
|
||||
|
||||
This tutorial shows you how to deploy `code-server` to a single node running on DigitalOcean.
|
||||
|
||||
If you're just starting out, we recommend [installing code-server locally](../../self-hosted/index.md). It takes only a few minutes and lets you try out all of the features. You can also try out the IDE on a container hosted [by Coder](http://coder.com/signup)
|
||||
|
||||
---
|
||||
|
||||
## Use the "Create Droplets" wizard
|
||||
|
||||
[Open your DigitalOcean dashboard](https://cloud.digitalocean.com/droplets/new) to create a new droplet
|
||||
|
||||
- **Choose an image -** Select the **Distributions** tab and then choose Ubuntu
|
||||
- **Choose a size -** We recommend at least 4GB RAM and 2 CPU, more depending on team size and number of repositories/languages enabled.
|
||||
- Launch your instance
|
||||
- Open a terminal on your computer and SSH into your instance
|
||||
> example: ssh root@203.0.113.0
|
||||
- Once in the SSH session, visit code-server [releases page](https://github.com/codercom/code-server/releases/) and copy the link to the download for the latest linux release
|
||||
- In the shell run the below command with the URL from your clipboard
|
||||
```
|
||||
wget https://github.com/codercom/code-server/releases/download/0.1.4/code-server-linux
|
||||
```
|
||||
- If you run into any permission errors when attempting to run the binary:
|
||||
```
|
||||
chmod +x code-server-linux
|
||||
```
|
||||
> To ensure the connection between you and your server is encrypted view our guide on [securing your setup](../security/ssl.md)
|
||||
- Finally start the code-server
|
||||
```
|
||||
sudo ./code-server-linux -p80
|
||||
```
|
||||
> For instructions on how to keep the server running after you end your SSH session please checkout [how to use systemd](https://www.linode.com/docs/quick-answers/linux/start-service-at-boot/) to start linux based services if they are killed
|
||||
- When you visit the public IP for your Digital Ocean instance, you will be greeted with this page. Code-server is using a self-signed SSL certificate for easy setup. To proceed to the IDE, click **"Advanced"**<img src ="../../assets/chrome_warning.png">
|
||||
- Then click **"proceed anyway"**<img src="../../assets/chrome_confirm.png">
|
||||
|
||||
---
|
||||
> NOTE: If you get stuck or need help, [file an issue](https://github.com/codercom/code-server/issues/new?&title=Improve+self-hosted+quickstart+guide), [tweet (@coderhq)](https://twitter.com/coderhq) or [email](mailto:support@coder.com?subject=Self-hosted%20quickstart%20guide).
|
||||
@@ -1,46 +0,0 @@
|
||||
# Deploy on Google Cloud
|
||||
|
||||
This tutorial shows you how to deploy `code-server` to a single node running on Google Cloud.
|
||||
|
||||
If you're just starting out, we recommend [installing code-server locally](../../self-hosted/index.md). It takes only a few minutes and lets you try out all of the features. You can also try out the IDE on a container hosted [by Coder](http://coder.com/signup)
|
||||
|
||||
---
|
||||
|
||||
## Deploy to Google Cloud VM
|
||||
> Pre-requisite: Please [set up Google Cloud SDK](https://cloud.google.com/sdk/docs/) on your local machine
|
||||
|
||||
- [Open your Google Cloud console](https://console.cloud.google.com/compute/instances) to create a new VM instance and click **Create Instance**
|
||||
- Choose an appropriate machine type (we recommend 2 vCPU and 7.5 GB RAM, more depending on team size and number of repositories/languages enabled)
|
||||
- Choose Ubuntu 16.04 LTS as your boot disk
|
||||
- Check the boxes for **Allow HTTP traffic** and **Allow HTTPS traffic** in the **Firewall** section
|
||||
- Create your VM, and **take note** of it's public IP address.
|
||||
- Copy the link to download the latest Linux binary from our [releases page](https://github.com/codercom/code-server/releases)
|
||||
|
||||
---
|
||||
|
||||
## Final Steps
|
||||
|
||||
1. SSH into your Google Cloud VM
|
||||
```
|
||||
gcloud compute ssh --zone [region] [instance name]
|
||||
```
|
||||
2. Download the binary using the link we copied to clipboard
|
||||
```
|
||||
wget https://github.com/codercom/code-server/releases/download/0.1.4/code-server-linux
|
||||
```
|
||||
3. Make the binary executable if you run into any errors regarding permission:
|
||||
```
|
||||
chmod +x code-server-linux
|
||||
```
|
||||
> To ensure the connection between you and your server is encrypted view our guide on [securing your setup](../security/ssl.md)
|
||||
4. Start the code-server
|
||||
```
|
||||
sudo ./code-server-linux -p 80
|
||||
```
|
||||
> For instructions on how to keep the server running after you end your SSH session please checkout [how to use systemd](https://www.linode.com/docs/quick-answers/linux/start-service-at-boot/) to start linux based services if they are killed
|
||||
5. Access code-server from the public IP of your Google Cloud instance we noted earlier in your browser.
|
||||
> example: 32.32.32.234
|
||||
6. You will be greeted with this page. Code-server is using a self-signed SSL certificate for easy setup. To proceed to the IDE, click **"Advanced"**<img src ="../../assets/chrome_warning.png">
|
||||
7. Then click **"proceed anyway"**<img src="../../assets/chrome_confirm.png">
|
||||
---
|
||||
> NOTE: If you get stuck or need help, [file an issue](https://github.com/codercom/code-server/issues/new?&title=Improve+self-hosted+quickstart+guide), [tweet (@coderhq)](https://twitter.com/coderhq) or [email](mailto:support@coder.com?subject=Self-hosted%20quickstart%20guide).
|
||||
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 161 KiB |
BIN
doc/assets/code-server.gif
Normal file
|
After Width: | Height: | Size: 4.0 MiB |
|
Before Width: | Height: | Size: 984 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 97 KiB |
245
doc/guide.md
Normal file
@@ -0,0 +1,245 @@
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
# Setup Guide
|
||||
|
||||
- [1. Acquire a remote machine](#1-acquire-a-remote-machine)
|
||||
- [Requirements](#requirements)
|
||||
- [Google Cloud](#google-cloud)
|
||||
- [2. Install code-server](#2-install-code-server)
|
||||
- [3. Expose code-server](#3-expose-code-server)
|
||||
- [SSH forwarding](#ssh-forwarding)
|
||||
- [Let's Encrypt](#lets-encrypt)
|
||||
- [Self Signed Certificate](#self-signed-certificate)
|
||||
- [Change the password?](#change-the-password)
|
||||
- [How do I securely access development web services?](#how-do-i-securely-access-development-web-services)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
This guide demonstrates how to setup and use code-server.
|
||||
To reiterate, code-server lets you run VS Code on a remote server and then access it via a browser.
|
||||
|
||||
See [README.md](../README.md) for a general overview and [FAQ.md](./FAQ.md) for further user docs.
|
||||
|
||||
We'll walk you through acquiring a remote machine to run code-server on and then exposing `code-server` so you can
|
||||
securely access it.
|
||||
|
||||
## 1. Acquire a remote machine
|
||||
|
||||
First, you need a machine to run code-server on. You can use a physical
|
||||
machine you have lying around or use a VM on GCP/AWS.
|
||||
|
||||
### Requirements
|
||||
|
||||
For a good experience, we recommend at least:
|
||||
|
||||
- 1 GB of RAM
|
||||
- 2 cores
|
||||
|
||||
You can use whatever linux distribution floats your boat but in this guide we assume Debian on Google Cloud.
|
||||
|
||||
### Google Cloud
|
||||
|
||||
For demonstration purposes, this guide assumes you're using a VM on GCP but you should be
|
||||
able to easily use any machine or VM provider.
|
||||
|
||||
You can sign up at https://console.cloud.google.com/getting-started. You'll get a 12 month \$300
|
||||
free trial.
|
||||
|
||||
Once you've signed up and created a GCP project, create a new Compute Engine VM Instance.
|
||||
|
||||
1. Navigate to `Compute Engine -> VM Instances` on the sidebar.
|
||||
2. Now click `Create Instance` to create a new instance.
|
||||
3. Name it whatever you want.
|
||||
4. Choose the region closest to you based on [gcping.com](http://www.gcping.com).
|
||||
5. Any zone is fine.
|
||||
6. We'd recommend a `E2` series instance from the General-purpose family.
|
||||
- Change the type to custom and set at least 2 cores and 2 GB of ram.
|
||||
- Add more vCPUs and memory as you prefer, you can edit after creating the instance as well.
|
||||
- https://cloud.google.com/compute/docs/machine-types#general_purpose
|
||||
7. We highly recommend switching the persistent disk to a SSD of at least 32 GB.
|
||||
- Click `Change` under `Boot Disk` and change the type to `SSD Persistent Disk` and the size
|
||||
to `32`.
|
||||
- You can always grow your disk later.
|
||||
- The default OS of Debian 10 is fine.
|
||||
8. Navigate to `Networking -> Network interfaces` and edit the existing interface
|
||||
to use a static external IP.
|
||||
- Click done to save network interface changes.
|
||||
9. If you do not have a [project wide SSH key](https://cloud.google.com/compute/docs/instances/adding-removing-ssh-keys#project-wide), navigate to `Security - > SSH Keys` and add your public key there.
|
||||
10. Click create!
|
||||
|
||||
Remember, you can shutdown your server when not in use to lower costs.
|
||||
We highly recommend learning to use the [`gcloud`](https://cloud.google.com/sdk/gcloud) cli
|
||||
to avoid the slow dashboard.
|
||||
|
||||
## 2. Install code-server
|
||||
|
||||
SSH into your instance and run the appropriate commands documented in [README.md](../README.md).
|
||||
|
||||
Assuming Debian:
|
||||
|
||||
```bash
|
||||
curl -sSOL https://github.com/cdr/code-server/releases/download/3.3.0/code-server_3.3.0_amd64.deb
|
||||
sudo dpkg -i code-server_3.3.0_amd64.deb
|
||||
systemctl --user enable --now code-server
|
||||
# Now code-server is running at http://127.0.0.1:8080
|
||||
# Your password is in ~/.config/code-server/config.yaml
|
||||
```
|
||||
|
||||
## 3. Expose code-server
|
||||
|
||||
**Never**, **ever** expose `code-server` directly to the internet without some form of authentication
|
||||
and encryption as someone can completely takeover your machine with the terminal.
|
||||
|
||||
There are several approaches to securely operating and exposing code-server.
|
||||
|
||||
By default, code-server will enable password authentication which will
|
||||
require you to copy the password from the code-server config file to login. You
|
||||
can also set a custom password with `$PASSWORD`.
|
||||
|
||||
**tip**: You can list the full set of code-server options with `code-server --help`
|
||||
|
||||
### SSH forwarding
|
||||
|
||||
We highly recommend this approach for not requiring any additional setup, you just need an
|
||||
SSH server on your remote machine. The downside is you won't be able to access `code-server`
|
||||
without an SSH client like an iPad. If that's important to you, skip to [Let's Encrypt](#lets-encrypt).
|
||||
|
||||
Recommended reading: https://help.ubuntu.com/community/SSH/OpenSSH/PortForwarding.
|
||||
|
||||
First, ssh into your instance and edit your code-server config file to disable password authentication.
|
||||
|
||||
```bash
|
||||
# Replaces "auth: password" with "auth: none" in the code-server config.
|
||||
sed -i.bak 's/auth: password/auth: none/' ~/.config/code-server/config.yaml
|
||||
```
|
||||
|
||||
Restart code-server with (assuming you followed the guide):
|
||||
|
||||
```bash
|
||||
systemctl --user restart code-server
|
||||
```
|
||||
|
||||
Now forward local port 8080 to `127.0.0.1:8080` on the remote instance.
|
||||
|
||||
```bash
|
||||
# -N disables executing a remote shell
|
||||
ssh -N -L 8080:127.0.0.1:8080 <instance-ip>
|
||||
```
|
||||
|
||||
Now if you access http://127.0.0.1:8080 locally, you should see code-server!
|
||||
|
||||
If you want to make the SSH port forwarding persistent we recommend using
|
||||
[mutagen](https://mutagen.io/documentation/introduction/installation).
|
||||
|
||||
```
|
||||
# Same as the above SSH command but runs in the background continously.
|
||||
# Add `mutagen daemon start` to your ~/.bashrc to start the mutagen daemon when you open a shell.
|
||||
mutagen forward create --name=code-server tcp:127.0.0.1:8080 <instance-ip>:tcp:127.0.0.1:8080
|
||||
```
|
||||
|
||||
We also recommend adding the following lines to your `~/.ssh/config` to quickly detect bricked SSH connections:
|
||||
|
||||
```bash
|
||||
Host *
|
||||
ServerAliveInterval 5
|
||||
ExitOnForwardFailure yes
|
||||
```
|
||||
|
||||
You can also forward your SSH key and GPG agent to the instance to securely access GitHub
|
||||
and sign commits without copying your keys onto the instance.
|
||||
|
||||
1. https://developer.github.com/v3/guides/using-ssh-agent-forwarding/
|
||||
2. https://wiki.gnupg.org/AgentForwarding
|
||||
|
||||
### Let's Encrypt
|
||||
|
||||
[Let's Encrypt](https://letsencrypt.org) is a great option if you want to access code-server on an iPad
|
||||
or do not want to use SSH forwarding. This does require that the remote machine is exposed to the internet.
|
||||
|
||||
Assuming you have been following the guide, edit your instance and checkmark the allow HTTP/HTTPS traffic options.
|
||||
|
||||
1. You'll need to buy a domain name. We recommend [Google Domains](https://domains.google.com).
|
||||
2. Add an A record to your domain with your instance's IP.
|
||||
3. Install caddy https://caddyserver.com/docs/download#debian-ubuntu-raspbian.
|
||||
|
||||
```bash
|
||||
echo "deb [trusted=yes] https://apt.fury.io/caddy/ /" \
|
||||
| sudo tee -a /etc/apt/sources.list.d/caddy-fury.list
|
||||
sudo apt update
|
||||
sudo apt install caddy
|
||||
```
|
||||
|
||||
4. Replace `/etc/caddy/Caddyfile` with sudo to look like this:
|
||||
|
||||
```
|
||||
mydomain.com
|
||||
|
||||
reverse_proxy 127.0.0.1:8080
|
||||
```
|
||||
|
||||
5. Reload caddy with:
|
||||
|
||||
```bash
|
||||
sudo systemctl reload caddy
|
||||
```
|
||||
|
||||
Visit `https://<your-domain-name>` to access code-server. Congratulations!
|
||||
|
||||
In a future release we plan to integrate Let's Encrypt directly with code-server to avoid
|
||||
the dependency on caddy.
|
||||
|
||||
### Self Signed Certificate
|
||||
|
||||
**note:** Self signed certificates do not work with iPad and will cause a blank page. You'll
|
||||
have to use [Let's Encrypt](#lets-encrypt) instead.
|
||||
|
||||
Recommended reading: https://security.stackexchange.com/a/8112.
|
||||
|
||||
We recommend this as a last resort as self signed certificates do not work with iPads and can
|
||||
cause other bizarre issues. Not to mention all the warnings when you access code-server.
|
||||
Only use this if:
|
||||
|
||||
1. You do not want to buy a domain.
|
||||
2. You cannot expose the remote machine to the internet.
|
||||
3. You do not want to use SSH forwarding.
|
||||
|
||||
ssh into your instance and edit your code-server config file to use a randomly generated self signed certificate:
|
||||
|
||||
```bash
|
||||
# Replaces "cert: false" with "cert: true" in the code-server config.
|
||||
sed -i.bak 's/cert: false/cert: true/' ~/.config/code-server/config.yaml
|
||||
# Replaces "bind-addr: 127.0.0.1:8080" with "bind-addr: 0.0.0.0:443" in the code-server config.
|
||||
sed -i.bak 's/bind-addr: 127.0.0.1:8080/bind-addr: 0.0.0.0:443/' ~/.config/code-server/config.yaml
|
||||
# Allows code-server to listen on port 443.
|
||||
sudo setcap cap_net_bind_service=+ep /usr/lib/code-server/lib/node
|
||||
```
|
||||
|
||||
Assuming you have been following the guide, restart code-server with:
|
||||
|
||||
```bash
|
||||
systemctl --user restart code-server
|
||||
```
|
||||
|
||||
Edit your instance and checkmark the allow HTTPS traffic option.
|
||||
|
||||
Visit `https://<your-instance-ip>` to access code-server.
|
||||
You'll get a warning when accessing but if you click through you should be good.
|
||||
|
||||
To avoid the warnings, you can use [mkcert](https://mkcert.dev) to create a self signed certificate
|
||||
trusted by your OS and then pass it into code-server via the `cert` and `cert-key` config
|
||||
fields.
|
||||
|
||||
### Change the password?
|
||||
|
||||
Edit the code-server config file at `~/.config/code-server/config.yaml` and then restart
|
||||
code-server with:
|
||||
|
||||
```bash
|
||||
systemctl --user restart code-server
|
||||
```
|
||||
|
||||
### How do I securely access development web services?
|
||||
|
||||
If you're working on a web service and want to access it locally, code-server can proxy it for you.
|
||||
|
||||
See [FAQ.md](https://github.com/cdr/code-server/blob/master/doc/FAQ.md#how-do-i-securely-access-web-services).
|
||||
34
doc/npm.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# npm Install Requirements
|
||||
|
||||
If you're installing the npm module you'll need certain dependencies to build
|
||||
the native modules used by VS Code.
|
||||
|
||||
You also need at least node v12 installed. See [#1633](https://github.com/cdr/code-server/issues/1633).
|
||||
|
||||
## Ubuntu, Debian
|
||||
|
||||
```bash
|
||||
sudo apt-get install -y \
|
||||
build-essential \
|
||||
pkg-config \
|
||||
libx11-dev \
|
||||
libxkbfile-dev \
|
||||
libsecret-1-dev
|
||||
```
|
||||
|
||||
## Fedora, Red Hat, SUSE
|
||||
|
||||
```bash
|
||||
sudo yum groupinstall -y 'Development Tools'
|
||||
sudo yum config-manager --set-enabled PowerTools
|
||||
sudo yum install -y python2 libsecret-devel libX11-devel libxkbfile-devel
|
||||
npm config set python python2
|
||||
```
|
||||
|
||||
## macOS
|
||||
|
||||
Install [Xcode](https://developer.apple.com/xcode/downloads/) and run:
|
||||
|
||||
```bash
|
||||
xcode-select --install
|
||||
```
|
||||
@@ -1,53 +0,0 @@
|
||||
# Generate a self-signed certificate đź”’
|
||||
|
||||
code-server has the ability to secure your connection between client and server using SSL/TSL certificates. By default, the server will start with an unencrypted connection. We recommend Self-signed TLS/SSL certificates for personal use of code-server or within an organization.
|
||||
|
||||
This guide will show you how to create a self-signed certificate and start code-server using your certificate/key.
|
||||
|
||||
## TLS / HTTPS
|
||||
|
||||
You can specify any location that you want to save the certificate and key. In this example, we will navigate to the root directory, create a folder called `certs` and cd into it.
|
||||
|
||||
```shell
|
||||
mkdir ~/certs && cd ~/certs
|
||||
```
|
||||
|
||||
If you don't already have a TLS certificate and key, you can generate them with the command below. They will be placed in `~/certs`
|
||||
|
||||
```shell
|
||||
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ~/certs/MyKey.key -out ~/certs/MyCertificate.crt
|
||||
```
|
||||
|
||||
You will be prompted to add some identifying information about your organization
|
||||
```shell
|
||||
You are about to be asked to enter information that will be incorporated
|
||||
into your certificate request.
|
||||
What you are about to enter is what is called a Distinguished Name or a DN.
|
||||
There are quite a few fields but you can leave some blank
|
||||
For some fields there will be a default value,
|
||||
If you enter '.', the field will be left blank.
|
||||
-----
|
||||
Country Name (2 letter code) [AU]:US
|
||||
State or Province Name (full name) [Some-State]:TX
|
||||
Locality Name (eg, city) []:Austin
|
||||
Organization Name (eg, company) [Coder Technologies]:Coder
|
||||
Organizational Unit Name (eg, section) []:Docs
|
||||
Common Name (e.g. server FQDN or YOUR name) []:hostname.example.com
|
||||
Email Address []:admin@example.com
|
||||
```
|
||||
>If you already have a TLS certificate and key, you can simply reference them in the `--cert` and `--cert-key` flags when launching code-server
|
||||
|
||||
|
||||
## Starting code-server with certificate and key
|
||||
|
||||
1. At the end of the path to your binary, add the following flags followed by the path to your certificate and key like so. Then press enter to run code-server.
|
||||
```shell
|
||||
./code-server --cert=~/certs/MyCertificate.crt --cert-key=~/certs/MyKey.key
|
||||
```
|
||||
2. After that you will be running a secure code-server.
|
||||
|
||||
> You will know your connection is secure if the lines `WARN No certificate specified. This could be insecure. WARN Documentation on securing your setup: https://coder.com/docs` no longer appear.
|
||||
|
||||
## Other options
|
||||
|
||||
For larger organizations you may wish to rely on a Certificate Authority as opposed to a self-signed certificate. For more information on generating free and open certificates for your site, please check out EFF's [certbot](https://certbot.eff.org/). Certbot is a cli to generate certificates using [LetsEncrypt](https://letsencrypt.org/).
|
||||
@@ -1,93 +0,0 @@
|
||||
# Getting Started
|
||||
|
||||
[code-server](https://coder.com) is used by developers at Azure, Google, Reddit, and more to give them access to VS Code in the browser.
|
||||
|
||||
## Quickstart guide
|
||||
|
||||
> NOTE: If you get stuck or need help, [file an issue](https://github.com/codercom/code-server/issues/new?&title=Improve+self-hosted+quickstart+guide), [tweet (@coderhq)](https://twitter.com/coderhq) or [email](mailto:support@coder.com?subject=Self-hosted%20quickstart%20guide).
|
||||
|
||||
This document pertains to Coder specific implementations of VS Code. For documentation on how to use VS Code itself, please refer to the official [documentation for VS Code](https://code.visualstudio.com/docs)
|
||||
|
||||
It takes just a few minutes to get your own self-hosted server running. If you've got a machine running macOS, Windows, or Linux, you're ready to start the binary which listens on port `8443` by default.
|
||||
|
||||
<!--
|
||||
DO NOT CHANGE THIS TO A CODEBLOCK.
|
||||
We want line breaks for readability, but backslashes to escape them do not work cross-platform.
|
||||
This uses line breaks that are rendered but not copy-pasted to the clipboard.
|
||||
-->
|
||||
|
||||
|
||||
1. Visit [the releases](https://github.com/codercom/code-server/releases) page and download the latest cli for your operating system
|
||||
2. Double click the executable to run in the current directory
|
||||
3. Copy the password that appears in the cli<img src="../assets/cli.png">
|
||||
4. In your browser navigate to `localhost:8443`
|
||||
5. Paste the password from the cli into the login window<img src="../assets/server-password-modal.png">
|
||||
> NOTE: Be careful with your password as sharing it will grant those users access to your server's file system
|
||||
|
||||
### Things to know
|
||||
- When you visit the IP for your code-server, you will be greeted with this page. Code-server is using a self-signed SSL certificate for easy setup. To proceed to the IDE, click **"Advanced"**<img src ="../assets/chrome_warning.png">
|
||||
- Then click **"proceed anyway"**<img src="../assets/chrome_confirm.png">
|
||||
|
||||
## Usage
|
||||
<pre class="pre-wrap"><code>code-server<span class="virtual-br"></span> --help</code></pre>
|
||||
|
||||
code-server can be ran with a number of arguments to customize your working directory, host, port, and SSL certificate.
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ code-server [WORKDIR]
|
||||
|
||||
ARGUMENTS
|
||||
WORKDIR [default: (directory to binary)] Specify working dir
|
||||
|
||||
OPTIONS
|
||||
-d, --data-dir=data-dir
|
||||
-h, --host=host [default: 0.0.0.0]
|
||||
-o, --open Open in browser on startup
|
||||
-p, --port=port [default: 8443] Port to bind on
|
||||
-v, --version show CLI version
|
||||
--allow-http
|
||||
--cert=cert
|
||||
--cert-key=cert-key
|
||||
--help show CLI help
|
||||
--no-auth
|
||||
--password=password
|
||||
```
|
||||
|
||||
### Data directory
|
||||
Use `code-server -d (path/to/directory)` or `code-server --data-dir=(path/to/directory)`, excluding the parentheses to specify the root folder that VS Code will start in
|
||||
|
||||
### Host
|
||||
By default, code-server will use `0.0.0.0` as its address. This can be changed by using `code-server -h` or `code-server --host=` followed by the address you want to use.
|
||||
> Example: `code-server -h 127.0.0.1`
|
||||
|
||||
### Open
|
||||
You can have the server automatically open the VS Code in your browser on startup by using the `code server -o` or `code-server --open` flags
|
||||
|
||||
### Port
|
||||
By default, code-server will use `8443` as its port. This can be changed by using `code-server -p` or `code-server --port=` followed by the port you want to use.
|
||||
> Example: `code-server -p 9000`
|
||||
|
||||
### Cert and Cert Key
|
||||
To encrypt the traffic between the browser and server use `code-server --cert=` followed by the path to your `.cer` file. Additionally, you can use certificate keys with `code-server --cert-key` followed by the path to your `.key` file.
|
||||
> Example (certificate and key): `code-server --cert /etc/letsencrypt/live/example.com/fullchain.cer --cert-key /etc/letsencrypt/live/example.com/fullchain.key`
|
||||
|
||||
> To ensure the connection between you and your server is encrypted view our guide on [securing your setup](../security/ssl.md)
|
||||
|
||||
### Nginx Reverse Proxy
|
||||
Nginx is for reverse proxy. Here is a example virtual host that works with code-server. Please also pass --allow-http. You can also use certbot by EFF to get a ssl certificates for free.
|
||||
```
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name code.example.com code.example.org;
|
||||
location / {
|
||||
proxy_pass http://localhost:8443/;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection upgrade;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Help
|
||||
Use `code-server -h` or `code-server --help` to view the usage for the cli. This is also shown at the beginning of this section.
|
||||
1
lib/vscode
Submodule
139
package.json
@@ -1,56 +1,99 @@
|
||||
{
|
||||
"name": "@coder/code-server",
|
||||
"repository": "https://github.com/codercom/code-server",
|
||||
"author": "Coder",
|
||||
"name": "code-server",
|
||||
"license": "MIT",
|
||||
"description": "Run VS Code remotely.",
|
||||
"scripts": {
|
||||
"build:rules": "cd ./rules && tsc -p .",
|
||||
"packages:install": "cd ./packages && yarn",
|
||||
"postinstall": "npm-run-all --parallel packages:install build:rules",
|
||||
"start": "cd ./packages/server && yarn start",
|
||||
"task": "ts-node -r tsconfig-paths/register build/tasks.ts",
|
||||
"test": "cd ./packages && yarn test"
|
||||
"version": "3.3.0",
|
||||
"description": "Run VS Code on a remote server.",
|
||||
"homepage": "https://github.com/cdr/code-server",
|
||||
"bugs": {
|
||||
"url": "https://github.com/cdr/code-server/issues"
|
||||
},
|
||||
"repository": "https://github.com/cdr/code-server",
|
||||
"scripts": {
|
||||
"clean": "./ci/build/clean.sh",
|
||||
"vscode": "./ci/dev/vscode.sh",
|
||||
"vscode:patch": "./ci/dev/patch-vscode.sh",
|
||||
"vscode:diff": "./ci/dev/diff-vscode.sh",
|
||||
"build": "./ci/build/build-code-server.sh",
|
||||
"build:vscode": "./ci/build/build-vscode.sh",
|
||||
"release": "./ci/build/build-release.sh",
|
||||
"release:static": "./ci/build/build-static-release.sh",
|
||||
"release:github-draft": "./ci/build/release-github-draft.sh",
|
||||
"release:github-assets": "./ci/build/release-github-assets.sh",
|
||||
"test:static-release": "./ci/build/test-static-release.sh",
|
||||
"package": "./ci/build/build-packages.sh",
|
||||
"_____": "",
|
||||
"fmt": "./ci/dev/fmt.sh",
|
||||
"lint": "./ci/dev/lint.sh",
|
||||
"test": "./ci/dev/test.sh",
|
||||
"ci": "./ci/dev/ci.sh",
|
||||
"watch": "NODE_OPTIONS=--max_old_space_size=32384 ts-node ./ci/dev/watch.ts"
|
||||
},
|
||||
"main": "out/node/entry.js",
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "^5.0.4",
|
||||
"@types/node": "^10.12.18",
|
||||
"@types/trash": "^4.3.1",
|
||||
"cross-env": "^5.2.0",
|
||||
"crypto-browserify": "^3.12.0",
|
||||
"css-loader": "^2.1.0",
|
||||
"file-loader": "^3.0.1",
|
||||
"fork-ts-checker-webpack-plugin": "^0.5.2",
|
||||
"fs-extra": "^7.0.1",
|
||||
"happypack": "^5.0.1",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"http-browserify": "^1.7.0",
|
||||
"ignore-loader": "^0.1.2",
|
||||
"mini-css-extract-plugin": "^0.5.0",
|
||||
"node-sass": "^4.11.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"path-browserify": "^1.0.0",
|
||||
"preload-webpack-plugin": "^3.0.0-beta.2",
|
||||
"sass-loader": "^7.1.0",
|
||||
"string-replace-loader": "^2.1.1",
|
||||
"style-loader": "^0.23.1",
|
||||
"ts-loader": "^5.3.3",
|
||||
"ts-node": "^7.0.1",
|
||||
"tsconfig-paths": "^3.8.0",
|
||||
"tslint": "^5.12.1",
|
||||
"typescript": "^3.2.2",
|
||||
"typescript-tslint-plugin": "^0.2.1",
|
||||
"uglifyjs-webpack-plugin": "^2.1.1",
|
||||
"webpack": "^4.28.4",
|
||||
"webpack-bundle-analyzer": "^3.0.3",
|
||||
"webpack-cli": "^3.2.1",
|
||||
"webpack-dev-middleware": "^3.5.0",
|
||||
"webpack-dev-server": "^3.1.14",
|
||||
"webpack-hot-middleware": "^2.24.3",
|
||||
"write-file-webpack-plugin": "^4.5.0"
|
||||
"@types/adm-zip": "^0.4.32",
|
||||
"@types/fs-extra": "^8.0.1",
|
||||
"@types/http-proxy": "^1.17.4",
|
||||
"@types/js-yaml": "^3.12.3",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "^12.12.7",
|
||||
"@types/parcel-bundler": "^1.12.1",
|
||||
"@types/pem": "^1.9.5",
|
||||
"@types/safe-compare": "^1.1.0",
|
||||
"@types/semver": "^7.1.0",
|
||||
"@types/tar-fs": "^1.16.2",
|
||||
"@types/tar-stream": "^1.6.1",
|
||||
"@types/ws": "^6.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^2.0.0",
|
||||
"@typescript-eslint/parser": "^2.0.0",
|
||||
"doctoc": "^1.4.0",
|
||||
"eslint": "^6.2.0",
|
||||
"eslint-config-prettier": "^6.0.0",
|
||||
"eslint-plugin-import": "^2.18.2",
|
||||
"eslint-plugin-prettier": "^3.1.0",
|
||||
"leaked-handles": "^5.2.0",
|
||||
"mocha": "^6.2.0",
|
||||
"parcel-bundler": "^1.12.4",
|
||||
"prettier": "^2.0.5",
|
||||
"stylelint": "^13.0.0",
|
||||
"stylelint-config-recommended": "^3.0.0",
|
||||
"ts-node": "^8.4.1",
|
||||
"typescript": "3.7.2"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/node": "^12.12.7",
|
||||
"safe-buffer": "^5.1.1",
|
||||
"vfile-message": "^2.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-loader": "^0.6.0",
|
||||
"webpack-merge": "^4.2.1"
|
||||
"@coder/logger": "1.1.11",
|
||||
"adm-zip": "^0.4.14",
|
||||
"env-paths": "^2.2.0",
|
||||
"fs-extra": "^8.1.0",
|
||||
"http-proxy": "^1.18.0",
|
||||
"httpolyglot": "^0.1.2",
|
||||
"js-yaml": "^3.13.1",
|
||||
"limiter": "^1.1.5",
|
||||
"pem": "^1.14.2",
|
||||
"safe-compare": "^1.1.4",
|
||||
"semver": "^7.1.3",
|
||||
"tar": "^6.0.1",
|
||||
"tar-fs": "^2.0.0",
|
||||
"ws": "^7.2.0",
|
||||
"xdg-basedir": "^4.0.0",
|
||||
"yarn": "^1.22.4"
|
||||
},
|
||||
"bin": {
|
||||
"code-server": "out/node/entry.js"
|
||||
},
|
||||
"keywords": [
|
||||
"vscode",
|
||||
"development",
|
||||
"ide",
|
||||
"coder",
|
||||
"vscode-remote",
|
||||
"browser-ide"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"name": "@coder/app",
|
||||
"scripts": {
|
||||
"start": "node ../../../node_modules/webpack-dev-server/bin/webpack-dev-server.js --config ./webpack.config.js",
|
||||
"build": "node ../../../node_modules/webpack/bin/webpack.js --config ./webpack.config.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@material/checkbox": "^0.44.1",
|
||||
"@material/textfield": "^0.44.1",
|
||||
"material-components-web": "^0.44.0"
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">
|
||||
<title>Authenticate: code-server</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="login">
|
||||
<div class="back">
|
||||
<- Back </div>
|
||||
<h4 class="title">code-server</h4>
|
||||
<h2 class="subtitle">
|
||||
Enter server password
|
||||
</h2>
|
||||
<div class="mdc-text-field">
|
||||
<input type="password" id="password" class="mdc-text-field__input" required>
|
||||
<label class="mdc-floating-label" for="password">Password</label>
|
||||
<div class="mdc-line-ripple"></div>
|
||||
</div>
|
||||
<button id="submit" class="mdc-button mdc-button--unelevated">
|
||||
<span class="mdc-button__label">Enter IDE</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,108 +0,0 @@
|
||||
@import url("https://use.typekit.net/vzk7ygg.css");
|
||||
|
||||
html, body {
|
||||
background-color: #FFFFFF;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'aktiv-grotesk';
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: calc(100vh - 20px);
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
--mdc-theme-primary: #AAADA1;
|
||||
--mdc-theme-secondary: #AAADA1;
|
||||
|
||||
&.in-app {
|
||||
.back {
|
||||
pointer-events: all;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.login {
|
||||
box-shadow: 0 18px 80px 10px rgba(69, 65, 78, 0.08);
|
||||
max-width: 328px;
|
||||
width: 100%;
|
||||
padding: 40px;
|
||||
border-radius: 5px;
|
||||
position: relative;
|
||||
color: #575962;
|
||||
|
||||
.title {
|
||||
margin-bottom: 0px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 1.5px;
|
||||
line-height: 15px;
|
||||
margin-bottom: 5px;
|
||||
margin-top: 0px;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
font-size: 19px;
|
||||
font-weight: bold;
|
||||
line-height: 25px;
|
||||
margin-bottom: 45px;
|
||||
}
|
||||
|
||||
.mdc-text-field {
|
||||
width: 100%;
|
||||
background: none !important;
|
||||
|
||||
&::before {
|
||||
background: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.mdc-form-field {
|
||||
text-align: left;
|
||||
font-size: 12px;
|
||||
color: #797E84;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.mdc-button {
|
||||
border-radius: 24px;
|
||||
padding-left: 75px;
|
||||
padding-right: 75px;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 15px;
|
||||
height: 48px;
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
box-shadow: 0 12px 17px 2px rgba(171,173,163,0.14), 0 5px 22px 4px rgba(171,173,163,0.12), 0 7px 8px -4px rgba(171,173,163,0.2);
|
||||
margin-top: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.mdc-text-field--focused:not(.mdc-text-field--disabled) .mdc-floating-label {
|
||||
color: var(--mdc-theme-primary);
|
||||
}
|
||||
|
||||
.mdc-floating-label--float-above {
|
||||
transform: translateY(-70%) scale(0.75);
|
||||
}
|
||||
|
||||
.mdc-text-field:not(.mdc-text-field--disabled):not(.mdc-text-field--outlined):not(.mdc-text-field--textarea) .mdc-text-field__input, .mdc-text-field:not(.mdc-text-field--disabled):not(.mdc-text-field--outlined):not(.mdc-text-field--textarea) .mdc-text-field__input:hover {
|
||||
border-bottom-color: #EBEDF2;
|
||||
}
|
||||
|
||||
.back {
|
||||
position: absolute;
|
||||
top: -50px;
|
||||
left: -50px;
|
||||
font-weight: bold;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
|
||||
// transition: 500ms opacity ease;
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
//@ts-ignore
|
||||
import { MDCTextField } from "@material/textfield";
|
||||
//@ts-ignore
|
||||
import { MDCCheckbox } from "@material/checkbox";
|
||||
import "material-components-web/dist/material-components-web.css";
|
||||
import "./app.scss";
|
||||
|
||||
document.querySelectorAll(".mdc-text-field").forEach((d) => new MDCTextField(d));
|
||||
document.querySelectorAll(".mdc-checkbox").forEach((d) => new MDCCheckbox(d));
|
||||
|
||||
window.addEventListener("message", (event) => {
|
||||
if (event.data === "app") {
|
||||
document.body.classList.add("in-app");
|
||||
|
||||
const back = document.querySelector(".back")!;
|
||||
back.addEventListener("click", () => {
|
||||
(event.source as Window).postMessage("back", event.origin);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const password = document.getElementById("password") as HTMLInputElement;
|
||||
const submit = document.getElementById("submit") as HTMLButtonElement;
|
||||
if (!submit) {
|
||||
throw new Error("No submit button found");
|
||||
}
|
||||
submit.addEventListener("click", () => {
|
||||
document.cookie = `password=${password.value}`;
|
||||
location.reload();
|
||||
});
|
||||
@@ -1,17 +0,0 @@
|
||||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const merge = require("webpack-merge");
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
|
||||
const root = path.resolve(__dirname, "../../..");
|
||||
|
||||
module.exports = merge(
|
||||
require(path.join(root, "scripts/webpack.client.config.js"))({
|
||||
entry: path.join(root, "packages/app/browser/src/app.ts"),
|
||||
template: path.join(root, "packages/app/browser/src/app.html"),
|
||||
}), {
|
||||
output: {
|
||||
path: path.join(__dirname, "out"),
|
||||
},
|
||||
},
|
||||
);
|
||||
@@ -1,606 +0,0 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@material/animation@^0.41.0":
|
||||
version "0.41.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/animation/-/animation-0.41.0.tgz#315b45b32e1aeebee8a4cf555b8ad52076d09ddd"
|
||||
integrity sha512-yYAwJbX3Q2AFd4dr6IYOsWLQy2HN8zWOFVl9AbUXunjzTfJCa/ecfXCriaT6qkmoNoHeTdJHRrsQJZC5GsPvzA==
|
||||
|
||||
"@material/auto-init@^0.41.0":
|
||||
version "0.41.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/auto-init/-/auto-init-0.41.0.tgz#8a59bb0b83e0f51ead9508074f9a29b2b6a20eec"
|
||||
integrity sha512-jp6L8MpYu7DudgDfA8iTyD9BwQrYPEDsIJGbqzN9vcCBl5FoBatkB8pcFXKr+1mRBk7T1Qmf6+H5nDtxyXjHEQ==
|
||||
|
||||
"@material/base@^0.41.0":
|
||||
version "0.41.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/base/-/base-0.41.0.tgz#badadce711b4c25b1eb889a5e7581e32cd07c421"
|
||||
integrity sha512-tEyzwBRu3d1H120SfKsDVYZHcqT5lKohh/7cWKR93aAaPDkSvjpKJIjyu2yuSkjpDduVZGzVocYbOvhUKhhzXQ==
|
||||
|
||||
"@material/button@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/button/-/button-0.44.0.tgz#f01dcbea88bdc314e7640b76e5558101c8b4d69d"
|
||||
integrity sha512-T8u8s8rlB49D9/5Nh5b0XsKRgSq3X0yWGo71MgaTnCnwxt8oZ6PxW/cH6Nn3Xp0NCr3mlSVQs08BviUfAmtlsg==
|
||||
dependencies:
|
||||
"@material/elevation" "^0.44.0"
|
||||
"@material/feature-targeting" "^0.44.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/shape" "^0.43.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
|
||||
"@material/card@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/card/-/card-0.44.0.tgz#e62050e3e77f525173a015119200055cd7b71bf0"
|
||||
integrity sha512-fUixXuh133bVp5c1gPIHreL5jwMJEeVIQf0E4xdxhkA+i4ku8fIAvIW62EuCmfJsXicv4q8NG3Ip6pCY+NW3ZA==
|
||||
dependencies:
|
||||
"@material/elevation" "^0.44.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/shape" "^0.43.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
|
||||
"@material/checkbox@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/checkbox/-/checkbox-0.44.0.tgz#5d0eee1db006db9f0fb700bf1c20408292305cf7"
|
||||
integrity sha512-IzucxG+NuPNyByGmHg/cuYJ5ooMKouuj994PZXZyqb7owfrjjtXm7wjav66cvCowbVbcoa1owQMGBi18C9f4TQ==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/selection-control" "^0.44.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
|
||||
"@material/checkbox@^0.44.1":
|
||||
version "0.44.1"
|
||||
resolved "https://registry.yarnpkg.com/@material/checkbox/-/checkbox-0.44.1.tgz#7e69271ccab7c57914a475da3a15d4d36702c1c4"
|
||||
integrity sha512-RFUNc+9RKRozL+gXfJ8V57tXfC31Q9R9tRMTHpe62NXZriTrwNJDnSkFIERDXqtMGtkKUnIlPfPE5znF6XyPUw==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/feature-targeting" "^0.44.1"
|
||||
"@material/ripple" "^0.44.1"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/selection-control" "^0.44.1"
|
||||
"@material/theme" "^0.43.0"
|
||||
|
||||
"@material/chips@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/chips/-/chips-0.44.0.tgz#bf553a5bf5db7320978402ac92069c9688b84d5a"
|
||||
integrity sha512-+qrme6sGwYmX/ixHAo3Z1M7lorsxRyKexn1l+BSBX5PBc2f4w5Ml1eYYYcyVGfLX9LXmefRk0G6dUXXPyCE00g==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/checkbox" "^0.44.0"
|
||||
"@material/elevation" "^0.44.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/shape" "^0.43.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
|
||||
"@material/dialog@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/dialog/-/dialog-0.44.0.tgz#388f93f9f225824c75cbe9da8c464a52d79972e8"
|
||||
integrity sha512-V6ButfknOMKOscL0Y39yLjamxvrIuyugobjf5s44ZeJc+9jUSkC7M3zP+T7rh358NcX+JSPP8iCGmUn/+LXpMQ==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/dom" "^0.41.0"
|
||||
"@material/elevation" "^0.44.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/shape" "^0.43.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
focus-trap "^4.0.2"
|
||||
|
||||
"@material/dom@^0.41.0":
|
||||
version "0.41.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/dom/-/dom-0.41.0.tgz#6756865f97bad4c91ee75e69d769d7cdc25398ae"
|
||||
integrity sha512-wOJrMwjPddYXpQFZAIaCLWI3TO/6KU1lxESTBzunni8A4FHQVWhokml5Xt85GqZwmPFeIF2s+D0wfbWyrGBuKQ==
|
||||
|
||||
"@material/drawer@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/drawer/-/drawer-0.44.0.tgz#74b3ddfb741bffc72331c7a73cf62716fd3f0ab3"
|
||||
integrity sha512-AYwFe0jgqqSmJd1bny8JJTA2SScF86Wfbk99lXXEwd/acS8IbnnuH6zfAg6MyJX12FDb8dE8Z/Ok1IwLiVa9sQ==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/elevation" "^0.44.0"
|
||||
"@material/list" "^0.44.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/shape" "^0.43.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
focus-trap "^4.0.2"
|
||||
|
||||
"@material/elevation@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/elevation/-/elevation-0.44.0.tgz#ca16a67188ce9810dc2fa3d7a39073e72df4b754"
|
||||
integrity sha512-edNou34yFCSMb6XXe/6Y7AEh8DigWAhBUyIeMiMBD4k1km2xYCJbcnl8FBPJFteOrca97KoJComRlJPB6EurRQ==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
|
||||
"@material/fab@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/fab/-/fab-0.44.0.tgz#0bcbbdfb6f24c53d59e08c9c0d400d2616dea184"
|
||||
integrity sha512-1CEP4NlXDYioJ/YpSjh/MlIygtoC7CaHqIbucxX1O5WRPmS7K1uPt+o7netbLErAmcJdV/JrI/tqh9kKuX2x/Q==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/elevation" "^0.44.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/shape" "^0.43.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
|
||||
"@material/feature-targeting@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/feature-targeting/-/feature-targeting-0.44.0.tgz#52cc73f0c8a83159de0357aebe74f15f9856fb4c"
|
||||
integrity sha512-ShuC2TOLfjFpYUCQFtvkqDJhM6HTaucSx5HkRbOvOG+VlpzDx6pAqRUmdVaq2p7tHoQf2vwPMlSVm3gOjWt4VQ==
|
||||
|
||||
"@material/feature-targeting@^0.44.1":
|
||||
version "0.44.1"
|
||||
resolved "https://registry.yarnpkg.com/@material/feature-targeting/-/feature-targeting-0.44.1.tgz#afafc80294e5efab94bee31a187273d43d34979a"
|
||||
integrity sha512-90cc7njn4aHbH9UxY8qgZth1W5JgOgcEdWdubH1t7sFkwqFxS5g3zgxSBt46TygFBVIXNZNq35Xmg80wgqO7Pg==
|
||||
|
||||
"@material/floating-label@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/floating-label/-/floating-label-0.44.0.tgz#8694cd49f6905641b67a9e7a112b820d028f09c7"
|
||||
integrity sha512-k4npGNxyMtnjgJZNjU5VvqqaUqlbzlbVAhepT8PxYTpj+4Skg6PjHwieTCDCgsbqHvFcQX+WfUrSZXY7wFV7cw==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
|
||||
"@material/floating-label@^0.44.1":
|
||||
version "0.44.1"
|
||||
resolved "https://registry.yarnpkg.com/@material/floating-label/-/floating-label-0.44.1.tgz#39af84a3a0abbfa6d210911d5f4200a65c2ef59b"
|
||||
integrity sha512-umj5q5feJcZuB8snRX5aVBrwQNnrt/HcvN7pENzgqaYZNcmBnxRl0OutTlHCn6l7OVU9VlWhFMf77DYwmMWKJQ==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.1"
|
||||
|
||||
"@material/form-field@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/form-field/-/form-field-0.44.0.tgz#b7518e885c0e953a2a5fe0140af927c30e066f4e"
|
||||
integrity sha512-SK+V34dzoBCQ/CHn5nBp8BAh21Vj9p1pcok+/WpYBTeg4EphTYP2nUQLMNEN92l6zjgAYf+g9Ocj3t26HNHWqA==
|
||||
dependencies:
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/selection-control" "^0.44.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
|
||||
"@material/grid-list@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/grid-list/-/grid-list-0.44.0.tgz#bd31d992ab1a910731e4a47c11fe91d44e3bc02b"
|
||||
integrity sha512-NxLL0A48K1O14ZZymFIyf6HDbF33+NgXYXqP2yosTC3Jw4iwmUcJTpFTmSw1U/m1xT4zEpeKEGJ4vjVUWpS9Mg==
|
||||
dependencies:
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
|
||||
"@material/icon-button@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/icon-button/-/icon-button-0.44.0.tgz#febbcfd27d91eca8096ae042b9c07ed0f65345e9"
|
||||
integrity sha512-n6L7RaRyEci6eGsuBTSEG+t9ATHAHaMlf9zuTWorEnIXY4DAmGO7ggBjw4+1XIOjhpLeIjyJdcvUK6Yz/UVM6Q==
|
||||
dependencies:
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
|
||||
"@material/icon-toggle@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/icon-toggle/-/icon-toggle-0.44.0.tgz#b9de32f194b5aa9721ca799d59be0f477a5c5305"
|
||||
integrity sha512-8T1b4iK61/q/3U0iIjEDJ9do5viCQ45IbrQqa8EYCZ1KDU/Q8z5N+bvOzQK8XnTL51BdDRMgP9lfQZh6nszmkA==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
|
||||
"@material/image-list@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/image-list/-/image-list-0.44.0.tgz#a27996962044ac8c9ce6cb509f63746f08ed2e98"
|
||||
integrity sha512-kI9aKJdc1Bd02l8nRTGG1wy/lNkECScfnBmCiLQ3XjAFtRYd2eWO0Z/AVvUG3egsIZnZBxqFGGsf5Htm9E/HiQ==
|
||||
dependencies:
|
||||
"@material/shape" "^0.43.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
|
||||
"@material/layout-grid@^0.41.0":
|
||||
version "0.41.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/layout-grid/-/layout-grid-0.41.0.tgz#2e7d3be76313e0684d573b10c2c6a88b3230d251"
|
||||
integrity sha512-Sa5RNoTGgfIojqJ9E94p7/k11V6q/tGk7HwKi4AQNAPjxield0zcl3G/SbsSb8YSHoK+D+7OXDN+n11x6EqF7g==
|
||||
|
||||
"@material/line-ripple@^0.43.0":
|
||||
version "0.43.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/line-ripple/-/line-ripple-0.43.0.tgz#6cb530bab53f055f3583646a21ad20c1703f3a83"
|
||||
integrity sha512-sXZYW4Em5uLEnAuVsQCO+sVHsTg7J2TOTJ0+akwZFMmd2tmNicjarQdlGIE9iU7Wjm51NOoLAu6Mz+8kLg90bQ==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
|
||||
"@material/linear-progress@^0.43.0":
|
||||
version "0.43.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/linear-progress/-/linear-progress-0.43.0.tgz#4821424aa24c78de256e74a91d5be3df55c534d9"
|
||||
integrity sha512-bqkDcob+xp1mFkyBsOkoaLgrtapmz7jznGoI3nmkqyk75EB2XQcn1H8Vr6cnp/jkF4nbKu0GdVJO3VXUFmGmrQ==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
|
||||
"@material/list@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/list/-/list-0.44.0.tgz#cf1910e15b66759334b8618d1110fbcc72c3d326"
|
||||
integrity sha512-35gkN1+XZaau9d9ngyN2x14bzkj/ajZCDm7mbWibDQy272A16j6KuFLQFA8RUQV04OgL4YPVxY87dpCn/p+uTg==
|
||||
dependencies:
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/dom" "^0.41.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/shape" "^0.43.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
|
||||
"@material/menu-surface@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/menu-surface/-/menu-surface-0.44.0.tgz#902c081df42859b925a5b4502791b3febf48f1ae"
|
||||
integrity sha512-s49kvIlQ4H5wvMD4yeHMMqnamPod06IUagMK6Ry0oTpUANSnyeNXxa3HkScl7DMJiS8IJeV21fSLAzlZYP2PDQ==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/elevation" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/shape" "^0.43.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
|
||||
"@material/menu@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/menu/-/menu-0.44.0.tgz#776ec8a04406266a0a0a13eb140b1fd691e442cb"
|
||||
integrity sha512-92XvAcv9rBW1jQ3UvwJ8zk9hbSRe/FqSuFdZ9fNPE348dCY2pbcdQfnUJTe3ycAN/I1c5frkrhx8F0II+nfbNQ==
|
||||
dependencies:
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/list" "^0.44.0"
|
||||
"@material/menu-surface" "^0.44.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
|
||||
"@material/notched-outline@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/notched-outline/-/notched-outline-0.44.0.tgz#d5a2e1d649921575a7cd2e88ee4581e4a1809573"
|
||||
integrity sha512-c3nqOqUQAmW3h4zBbZVbMRdf4nNTYm0tVwXIAwmcCs5nvAthEHnzHwwFddNP7/9Wju6LZ0uqWn6xlyKly0uipw==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/floating-label" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/shape" "^0.43.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
|
||||
"@material/notched-outline@^0.44.1":
|
||||
version "0.44.1"
|
||||
resolved "https://registry.yarnpkg.com/@material/notched-outline/-/notched-outline-0.44.1.tgz#dba4812286ba4c20f0361e6040bf9b9cad307434"
|
||||
integrity sha512-x1ZJtrrqZgXT8gYE7aRF+6hTWpX7XaKZzsuwD+e0HBsogYNNsYmkBdLjl4YwhhFuHhX8vWzgkay41GtbgQx84Q==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/floating-label" "^0.44.1"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/shape" "^0.44.1"
|
||||
"@material/theme" "^0.43.0"
|
||||
|
||||
"@material/radio@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/radio/-/radio-0.44.0.tgz#f4cacdfabc7d765aa000cb34c5a37966f6d4fd6d"
|
||||
integrity sha512-ar7uhlfHuSwM9JUUjpv7pLDLE0p436cCMxNTpmMjWabfvo3pMWlExvk72Oj81tBgfxY/uASLB3oj4neudXu9JQ==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/selection-control" "^0.44.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
|
||||
"@material/ripple@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/ripple/-/ripple-0.44.0.tgz#98920ff8ec4bf5714c97df3d190f02f8a5b476cc"
|
||||
integrity sha512-MlaW4nUDgzS0JOBfsUawXyTOilr0jn+xvTVn6PEaGh2rmhNA54AhixXvdsVUWE9lfmHAsZV0AJHz2z7nunNhbQ==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/feature-targeting" "^0.44.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
|
||||
"@material/ripple@^0.44.1":
|
||||
version "0.44.1"
|
||||
resolved "https://registry.yarnpkg.com/@material/ripple/-/ripple-0.44.1.tgz#79cb2ddf1f998498d877d3e3c46b50fed6f13b01"
|
||||
integrity sha512-prJ1p3bR+GvwAtJgtdeIixsnRVApN3bizGnX7upKoqxsqbBDHj84JxaO8EsG9bjruG/LJu8Fb6WKKdIp2oXHTA==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/feature-targeting" "^0.44.1"
|
||||
"@material/theme" "^0.43.0"
|
||||
|
||||
"@material/rtl@^0.42.0":
|
||||
version "0.42.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/rtl/-/rtl-0.42.0.tgz#1836e78186c2d8b996f6fbf97adab203535335bc"
|
||||
integrity sha512-VrnrKJzhmspsN8WXHuxxBZ69yM5IwhCUqWr1t1eNfw3ZEvEj7i1g3P31HGowKThIN1dc1Wh4LE14rCISWCtv5w==
|
||||
|
||||
"@material/select@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/select/-/select-0.44.0.tgz#8041b4fe6247d013b0f12685fbdf50aa9ff57b35"
|
||||
integrity sha512-tw3/QIBLuRCT+5IXx4IPiJk7FzeGeR65JEizdRUItH8yzoIiQLs/b2i3KtHM2YBXHgeUcEBF2AOqPX2opdYhug==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/floating-label" "^0.44.0"
|
||||
"@material/line-ripple" "^0.43.0"
|
||||
"@material/menu" "^0.44.0"
|
||||
"@material/menu-surface" "^0.44.0"
|
||||
"@material/notched-outline" "^0.44.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/shape" "^0.43.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
|
||||
"@material/selection-control@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/selection-control/-/selection-control-0.44.0.tgz#63d5c65a47a9f54f5a0316b5ecdb5e5f35108609"
|
||||
integrity sha512-HgCAPnMVMEj4X4ILkFSifqtZ3Tcc5HkU+Lfk9g0807sCaN/qBKWkYKLH2WJUbW8uk+MXK7DgP1khtS5zzanJWA==
|
||||
dependencies:
|
||||
"@material/ripple" "^0.44.0"
|
||||
|
||||
"@material/selection-control@^0.44.1":
|
||||
version "0.44.1"
|
||||
resolved "https://registry.yarnpkg.com/@material/selection-control/-/selection-control-0.44.1.tgz#77a47354a4c5128fa34e3ba98d9cc26e8a92839a"
|
||||
integrity sha512-Xf1ee2ZV2XJ+rK8OcOD1DZOihfU0uVRdY6iYX/Bqi8k8RXnAbLIBoh6zG3xSwjRNODNvAyHEQaS/ozEfH8eehg==
|
||||
dependencies:
|
||||
"@material/ripple" "^0.44.1"
|
||||
|
||||
"@material/shape@^0.43.0":
|
||||
version "0.43.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/shape/-/shape-0.43.0.tgz#b877acfd8be8abc9ddcf6601eb60dd0588292415"
|
||||
integrity sha512-KGnoQV4G2OQbMe5Lr5Xbk8XNlO93Qi/juxXtd2wrAfiaPmktD8ug0CwdVDOPBOmj9a0gX3Ofi9XWcoU+tLEVjg==
|
||||
|
||||
"@material/shape@^0.44.1":
|
||||
version "0.44.1"
|
||||
resolved "https://registry.yarnpkg.com/@material/shape/-/shape-0.44.1.tgz#ff4d5d42b07c5781306677bffee43234b756ea8e"
|
||||
integrity sha512-8mCDQmyTEhDK+HX8Tap2Lc82QlVySlXU8zDCNkWoIn1ge+UnRezSDjE4y4P1ABegN5PrkJZPartuQ1U0ttIYXw==
|
||||
dependencies:
|
||||
"@material/feature-targeting" "^0.44.1"
|
||||
|
||||
"@material/slider@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/slider/-/slider-0.44.0.tgz#2055df894eb725e541cde50a544719c07934755b"
|
||||
integrity sha512-Lnn2fdUesXX4O0UpJzveEuOj+og+dXCwhal73u3l3NXEdc/eRgYxwWdF3ww4MmCZ786EwUmjb4vIc9olN4DO3A==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
|
||||
"@material/snackbar@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/snackbar/-/snackbar-0.44.0.tgz#d98672b849f5f295e4fac2d474a9c80f11945518"
|
||||
integrity sha512-KhCrmJm8Zu/ZZPuRCGfMKsZ0vudINlNgTjlOau0kQ/UgR1xBUvLOE8NjyXZr0RQz5obyW7xpyIWIpscn0IUeyw==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/button" "^0.44.0"
|
||||
"@material/dom" "^0.41.0"
|
||||
"@material/icon-button" "^0.44.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/shape" "^0.43.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
|
||||
"@material/switch@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/switch/-/switch-0.44.0.tgz#f2cbb447437b12eb3bc7f0ec8318dbd3b4f0afce"
|
||||
integrity sha512-EadCg6lHUF260R2Q/l++vXIITqacvbXlobSoewA5ib6y9BU2g7l13wL1W8xAVJNUMgFa/PyN+EKT3oCql7jZLg==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/elevation" "^0.44.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/selection-control" "^0.44.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
|
||||
"@material/tab-bar@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/tab-bar/-/tab-bar-0.44.0.tgz#b17d791bd557b1d84892fef1a1d8b8d6fef7c6d6"
|
||||
integrity sha512-kCrt05d61YXyY43SNc0dPGuqysbcLr/KRDBvzpXgE4gv2jCCVhhjAH10KPlx8pthp/UtvrYJHb34acAKEGzdHA==
|
||||
dependencies:
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/elevation" "^0.44.0"
|
||||
"@material/tab" "^0.44.0"
|
||||
"@material/tab-scroller" "^0.44.0"
|
||||
|
||||
"@material/tab-indicator@^0.43.0":
|
||||
version "0.43.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/tab-indicator/-/tab-indicator-0.43.0.tgz#37fd05513ba55ae218d9068c986c2676096fd6eb"
|
||||
integrity sha512-RMNMQpWYghWpM6d0ayfuHEPzTiebKG0bMthViiD6tly8PubmOT8mShNhPm8ihybhDPUOLSz+7V4QNE5wikLEYg==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
|
||||
"@material/tab-scroller@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/tab-scroller/-/tab-scroller-0.44.0.tgz#82d092ed45d2ee9d82038bed318e6ff6bdc36dad"
|
||||
integrity sha512-Ufd3NWBN11kY2oA7bGmTYWGP1uz2mq0tfDM0JOiqoLMgD7y3Z18kmxnpq2qkg1vi4kvix28hBYGGMfLlq9rGDA==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/tab" "^0.44.0"
|
||||
|
||||
"@material/tab@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/tab/-/tab-0.44.0.tgz#254b92cff99015f0bd59a86d08d3f1c4744d0742"
|
||||
integrity sha512-czrbGjtKkmUS3iYBX523xT5GOkjP0h+0x9fTnw+heFNpw5dCn6cZvlj3D9ayZU+ZH93x68TFhFVBuLU5f0EBXw==
|
||||
dependencies:
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/tab-indicator" "^0.43.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
|
||||
"@material/textfield@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/textfield/-/textfield-0.44.0.tgz#277b33948ddff33f7f643323895e5a683f013601"
|
||||
integrity sha512-IMBwMcE82eVU+Wifpu0t84tozvBPLCeqQELDtZNYujKg3RxaultzJLwIyGKPMZ9R4yPEpV2vgXPGKE+2/AWt0g==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/floating-label" "^0.44.0"
|
||||
"@material/line-ripple" "^0.43.0"
|
||||
"@material/notched-outline" "^0.44.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/shape" "^0.43.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
|
||||
"@material/textfield@^0.44.1":
|
||||
version "0.44.1"
|
||||
resolved "https://registry.yarnpkg.com/@material/textfield/-/textfield-0.44.1.tgz#2bba41cc94e68e328683997a1acf222b643dea9c"
|
||||
integrity sha512-zy+56+uqr+L9DGrdOfQjOIMdKlai/7ruyqVfqIY6ieABM7LEGsOsxHhyExQmXo9IiuFhrOceWKFa4yIb8jBsmQ==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/floating-label" "^0.44.1"
|
||||
"@material/line-ripple" "^0.43.0"
|
||||
"@material/notched-outline" "^0.44.1"
|
||||
"@material/ripple" "^0.44.1"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/shape" "^0.44.1"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.1"
|
||||
|
||||
"@material/theme@^0.43.0":
|
||||
version "0.43.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/theme/-/theme-0.43.0.tgz#6d9fa113c82e841817882172c152d60d2d203ca6"
|
||||
integrity sha512-/zndZL6EihI18v2mYd4O8xvOBAAXmLeHyHVK28LozSAaJ9okQgD25wq5Ktk95oMTmPIC+rH66KcK6371ivNk8g==
|
||||
|
||||
"@material/toolbar@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/toolbar/-/toolbar-0.44.0.tgz#6689aecdeccc78b7a890a3abbe8b68a2c6339307"
|
||||
integrity sha512-YgLlOFQ5VzFLQBpXYSMviEbYox0fia+sasHuYPUhTAtas1ExVt9EEiIolDSVvhv2PruTReKKefxSbXAqGlOHog==
|
||||
dependencies:
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/elevation" "^0.44.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
|
||||
"@material/top-app-bar@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/top-app-bar/-/top-app-bar-0.44.0.tgz#2495c7f9567568fb961ccced24f479c4806a72af"
|
||||
integrity sha512-tf0yXQJARYs8UPaH8oo3LnsSHEiur7Zm8Fc3hv3F0gNRRaZYBjwsMQMVbZZaWoQCWskMALyntBg+Fo18zdgDxw==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/elevation" "^0.44.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/shape" "^0.43.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
|
||||
"@material/typography@^0.44.0":
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/@material/typography/-/typography-0.44.0.tgz#cf61dce2ee89bfa084d86e1b0f270a585bf9dfaf"
|
||||
integrity sha512-m4SjA9OjZRDKowN3cPzEa8e2GlTlEn3ZmW/Fy9eRNSp83iY+8a0xl6kCaF80v5qAVwVcpfEFyEHWxMJtkBw2uA==
|
||||
|
||||
"@material/typography@^0.44.1":
|
||||
version "0.44.1"
|
||||
resolved "https://registry.yarnpkg.com/@material/typography/-/typography-0.44.1.tgz#a94f01172f9122180bc2ce0aa55658183a35590d"
|
||||
integrity sha512-wMXHusg+Lp5Fdgoj3m0c+Lt6GCeGSh3EPRtQ1TQ2bwdBa0et2FqBaQRgXoq3tVmr0O/7unTfa0DoXlh4nVp1wA==
|
||||
dependencies:
|
||||
"@material/feature-targeting" "^0.44.1"
|
||||
|
||||
focus-trap@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-4.0.2.tgz#4ee2b96547c9ea0e4252a2d4b2cca68944194663"
|
||||
integrity sha512-HtLjfAK7Hp2qbBtLS6wEznID1mPT+48ZnP2nkHzgjpL4kroYHg0CdqJ5cTXk+UO5znAxF5fRUkhdyfgrhh8Lzw==
|
||||
dependencies:
|
||||
tabbable "^3.1.2"
|
||||
xtend "^4.0.1"
|
||||
|
||||
material-components-web@^0.44.0:
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/material-components-web/-/material-components-web-0.44.0.tgz#ff782e8d7bdd8212d3c6022a731258d0d42da531"
|
||||
integrity sha512-BSRLf58SMVhAvlDhJDlcgYuvzeMwbMHKTJ7oIB8LaM24ZpXBxP9XCYJpKheMtiVLrgllCGDlJ/47OIDReHQXdQ==
|
||||
dependencies:
|
||||
"@material/animation" "^0.41.0"
|
||||
"@material/auto-init" "^0.41.0"
|
||||
"@material/base" "^0.41.0"
|
||||
"@material/button" "^0.44.0"
|
||||
"@material/card" "^0.44.0"
|
||||
"@material/checkbox" "^0.44.0"
|
||||
"@material/chips" "^0.44.0"
|
||||
"@material/dialog" "^0.44.0"
|
||||
"@material/dom" "^0.41.0"
|
||||
"@material/drawer" "^0.44.0"
|
||||
"@material/elevation" "^0.44.0"
|
||||
"@material/fab" "^0.44.0"
|
||||
"@material/feature-targeting" "^0.44.0"
|
||||
"@material/floating-label" "^0.44.0"
|
||||
"@material/form-field" "^0.44.0"
|
||||
"@material/grid-list" "^0.44.0"
|
||||
"@material/icon-button" "^0.44.0"
|
||||
"@material/icon-toggle" "^0.44.0"
|
||||
"@material/image-list" "^0.44.0"
|
||||
"@material/layout-grid" "^0.41.0"
|
||||
"@material/line-ripple" "^0.43.0"
|
||||
"@material/linear-progress" "^0.43.0"
|
||||
"@material/list" "^0.44.0"
|
||||
"@material/menu" "^0.44.0"
|
||||
"@material/menu-surface" "^0.44.0"
|
||||
"@material/notched-outline" "^0.44.0"
|
||||
"@material/radio" "^0.44.0"
|
||||
"@material/ripple" "^0.44.0"
|
||||
"@material/rtl" "^0.42.0"
|
||||
"@material/select" "^0.44.0"
|
||||
"@material/selection-control" "^0.44.0"
|
||||
"@material/shape" "^0.43.0"
|
||||
"@material/slider" "^0.44.0"
|
||||
"@material/snackbar" "^0.44.0"
|
||||
"@material/switch" "^0.44.0"
|
||||
"@material/tab" "^0.44.0"
|
||||
"@material/tab-bar" "^0.44.0"
|
||||
"@material/tab-indicator" "^0.43.0"
|
||||
"@material/tab-scroller" "^0.44.0"
|
||||
"@material/textfield" "^0.44.0"
|
||||
"@material/theme" "^0.43.0"
|
||||
"@material/toolbar" "^0.44.0"
|
||||
"@material/top-app-bar" "^0.44.0"
|
||||
"@material/typography" "^0.44.0"
|
||||
|
||||
tabbable@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-3.1.2.tgz#f2d16cccd01f400e38635c7181adfe0ad965a4a2"
|
||||
integrity sha512-wjB6puVXTYO0BSFtCmWQubA/KIn7Xvajw0x0l6eJUudMG/EAiJvIUnyNX6xO4NpGrJ16lbD0eUseB9WxW0vlpQ==
|
||||
|
||||
xtend@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
|
||||
integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68=
|
||||
|
Before Width: | Height: | Size: 537 B |
@@ -1,42 +0,0 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "Coder",
|
||||
"version": "1",
|
||||
"icons": {
|
||||
"128": "icon_128.png"
|
||||
},
|
||||
"permissions": [
|
||||
"storage",
|
||||
"webview",
|
||||
"http://*/*",
|
||||
"https://*/*"
|
||||
],
|
||||
"app": {
|
||||
"background": {
|
||||
"scripts": [
|
||||
"out/background.js"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"scripts": [
|
||||
"out/content.js"
|
||||
]
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
"toggle-feature-foo": {
|
||||
"suggested_key": {
|
||||
"default": "Ctrl+W"
|
||||
},
|
||||
"description": "Toggle feature foo",
|
||||
"global": true
|
||||
}
|
||||
},
|
||||
"sockets": {
|
||||
"tcpServer": {
|
||||
"listen": [
|
||||
""
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"name": "@coder/chrome-app",
|
||||
"dependencies": {
|
||||
"@types/chrome": "^0.0.79"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "../../../node_modules/.bin/webpack --config ./webpack.config.js"
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
/// <reference path="../node_modules/@types/chrome/index.d.ts" />
|
||||
|
||||
// tslint:disable-next-line:no-any
|
||||
const chromeApp = (<any>chrome).app;
|
||||
|
||||
chromeApp.runtime.onLaunched.addListener(() => {
|
||||
chromeApp.window.create("src/index.html", {
|
||||
outerBounds: {
|
||||
width: 400,
|
||||
height: 500,
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -1,92 +0,0 @@
|
||||
//@ts-ignore
|
||||
import { TcpHost, TcpServer, TcpConnection } from "@coder/app/common/src/app";
|
||||
import { Event, Emitter } from "@coder/events/src";
|
||||
|
||||
export const tcpHost: TcpHost = {
|
||||
listen(host: string, port: number): Promise<TcpServer> {
|
||||
const socketApi: {
|
||||
readonly tcpServer: {
|
||||
create(props: {}, cb: (createInfo: { readonly socketId: number }) => void): void;
|
||||
listen(socketId: number, address: string, port: number, callback: (result: number) => void): void;
|
||||
disconnect(socketId: number, callback: () => void): void;
|
||||
|
||||
readonly onAccept: {
|
||||
addListener(callback: (info: { readonly socketId: number; readonly clientSocketId: number }) => void): void;
|
||||
};
|
||||
};
|
||||
readonly tcp: {
|
||||
readonly onReceive: {
|
||||
addListener(callback: (info: { readonly socketId: number; readonly data: ArrayBuffer; }) => void): void;
|
||||
};
|
||||
close(socketId: number, callback?: () => void): void;
|
||||
send(socketId: number, data: ArrayBuffer, callback?: () => void): void;
|
||||
setPaused(socketId: number, value: boolean): void;
|
||||
};
|
||||
// tslint:disable-next-line:no-any
|
||||
} = (<any>chrome).sockets;
|
||||
|
||||
return new Promise((resolve, reject): void => {
|
||||
socketApi.tcpServer.create({}, (createInfo) => {
|
||||
const serverSocketId = createInfo.socketId;
|
||||
socketApi.tcpServer.listen(serverSocketId, host, port, (result) => {
|
||||
if (result < 0) {
|
||||
return reject("Failed to listen: " + chrome.runtime.lastError);
|
||||
}
|
||||
|
||||
const connectionEmitter = new Emitter<TcpConnection>();
|
||||
|
||||
socketApi.tcpServer.onAccept.addListener((info) => {
|
||||
if (info.socketId !== serverSocketId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dataEmitter = new Emitter<ArrayBuffer>();
|
||||
|
||||
socketApi.tcp.onReceive.addListener((recvInfo) => {
|
||||
if (recvInfo.socketId !== info.clientSocketId) {
|
||||
return;
|
||||
}
|
||||
|
||||
dataEmitter.emit(recvInfo.data);
|
||||
});
|
||||
|
||||
socketApi.tcp.setPaused(info.clientSocketId, false);
|
||||
|
||||
connectionEmitter.emit({
|
||||
send: (data): Promise<void> => {
|
||||
return new Promise<void>((res): void => {
|
||||
socketApi.tcp.send(info.clientSocketId, data, () => {
|
||||
res();
|
||||
});
|
||||
});
|
||||
},
|
||||
close: (): Promise<void> => {
|
||||
return new Promise((res): void => {
|
||||
socketApi.tcp.close(info.clientSocketId, () => {
|
||||
res();
|
||||
});
|
||||
});
|
||||
},
|
||||
get onData(): Event<ArrayBuffer> {
|
||||
return dataEmitter.event;
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
resolve({
|
||||
get onConnection(): Event<TcpConnection> {
|
||||
return connectionEmitter.event;
|
||||
},
|
||||
close: (): Promise<void> => {
|
||||
return new Promise((res): void => {
|
||||
socketApi.tcpServer.disconnect(serverSocketId, () => {
|
||||
res();
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
@@ -1,33 +0,0 @@
|
||||
import { create } from "@coder/app/common/src/app";
|
||||
import { tcpHost } from "./chome";
|
||||
|
||||
create({
|
||||
storage: {
|
||||
get: <T>(key: string): Promise<T | undefined> => {
|
||||
return new Promise<T | undefined>((resolve, reject): void => {
|
||||
try {
|
||||
chrome.storage.sync.get(key, (items) => {
|
||||
resolve(items[key]);
|
||||
});
|
||||
} catch (ex) {
|
||||
reject(ex);
|
||||
}
|
||||
});
|
||||
},
|
||||
set: <T>(key: string, value: T): Promise<void> => {
|
||||
return new Promise<void>((resolve, reject): void => {
|
||||
try {
|
||||
chrome.storage.sync.set({
|
||||
[key]: value,
|
||||
}, () => {
|
||||
resolve();
|
||||
});
|
||||
} catch (ex) {
|
||||
reject(ex);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
tcp: tcpHost,
|
||||
node: document.getElementById("main") as HTMLDivElement,
|
||||
});
|
||||
@@ -1,15 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="style-src 'self' https://use.typekit.net; font-src 'self' https://use.typekit.net;">
|
||||
<link rel="stylesheet" type="text/css" href="/out/main.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="main"></div>
|
||||
<script src="/out/content.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,37 +0,0 @@
|
||||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const merge = require("webpack-merge");
|
||||
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const prod = process.env.NODE_ENV === "production";
|
||||
|
||||
module.exports = [
|
||||
merge(require(path.join(__dirname, "../../../scripts", "webpack.general.config.js"))(), {
|
||||
devtool: "none",
|
||||
mode: "development",
|
||||
target: "web",
|
||||
output: {
|
||||
path: path.join(__dirname, "out"),
|
||||
filename: "background.js",
|
||||
},
|
||||
entry: [
|
||||
"./packages/app/chrome/src/background.ts"
|
||||
],
|
||||
plugins: [
|
||||
]
|
||||
}),
|
||||
merge(require(path.join(__dirname, "../../../scripts", "webpack.general.config.js"))(), {
|
||||
devtool: "none",
|
||||
mode: "development",
|
||||
target: "web",
|
||||
output: {
|
||||
path: path.join(__dirname, "out"),
|
||||
filename: "content.js",
|
||||
},
|
||||
entry: [
|
||||
"./packages/app/chrome/src/content.ts"
|
||||
],
|
||||
plugins: [
|
||||
]
|
||||
}),
|
||||
];
|
||||
@@ -1,22 +0,0 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/chrome@^0.0.79":
|
||||
version "0.0.79"
|
||||
resolved "https://registry.yarnpkg.com/@types/chrome/-/chrome-0.0.79.tgz#1c83b35bd9b21b6204fb56e4816a1ea65dc013e5"
|
||||
integrity sha512-4+Xducpig6lpwVX65Hk8KSZwRoURHXMDbd38SDNcV8TBaw4xyJki39fjB1io2h7ip+BsyFvgTm9OxR5qneLPiA==
|
||||
dependencies:
|
||||
"@types/filesystem" "*"
|
||||
|
||||
"@types/filesystem@*":
|
||||
version "0.0.29"
|
||||
resolved "https://registry.yarnpkg.com/@types/filesystem/-/filesystem-0.0.29.tgz#ee3748eb5be140dcf980c3bd35f11aec5f7a3748"
|
||||
integrity sha512-85/1KfRedmfPGsbK8YzeaQUyV1FQAvMPMTuWFQ5EkLd2w7szhNO96bk3Rh/SKmOfd9co2rCLf0Voy4o7ECBOvw==
|
||||
dependencies:
|
||||
"@types/filewriter" "*"
|
||||
|
||||
"@types/filewriter@*":
|
||||
version "0.0.28"
|
||||
resolved "https://registry.yarnpkg.com/@types/filewriter/-/filewriter-0.0.28.tgz#c054e8af4d9dd75db4e63abc76f885168714d4b3"
|
||||
integrity sha1-wFTor02d11205jq8dviFFocU1LM=
|
||||
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"name": "@coder/app-common",
|
||||
"main": "src/app.ts",
|
||||
"dependencies": {
|
||||
"material-components-web": "^0.44.0",
|
||||
"react": "^16.8.1",
|
||||
"react-dom": "^16.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^16.8.2",
|
||||
"@types/react-dom": "^16.8.0"
|
||||
}
|
||||
}
|
||||
@@ -1,279 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'aktiv-grotesk';
|
||||
font-weight: 400;
|
||||
// src: url("fonts/AktivGroteskRegular.ttf"); /* IE9 Compat Modes */
|
||||
src: url("fonts/AktivGroteskRegular.woff2") format("woff2"), url("fonts/AktivGroteskRegular.woff") format("woff"); /* Pretty Modern Browsers */
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'aktiv-grotesk';
|
||||
font-weight: 500;
|
||||
src: url("fonts/AktivGroteskMedium.woff2") format("woff2"), url("fonts/AktivGroteskMedium.woff") format("woff"); /* Pretty Modern Browsers */
|
||||
// src: url("fonts/AktivGroteskMedium.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'aktiv-grotesk';
|
||||
font-weight: 700;
|
||||
src: url("fonts/AktivGroteskBold.woff2") format("woff2"), url("fonts/AktivGroteskBold.woff") format("woff"); /* Pretty Modern Browsers */
|
||||
// src: url("fonts/AktivGroteskBold.ttf") format("ttf"); /* IE9 Compat Modes */
|
||||
}
|
||||
|
||||
body, button, input {
|
||||
font-family: 'aktiv-grotesk',sans-serif !important;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background-color: #F6F8FB;
|
||||
--mdc-theme-primary: #2A2E37;
|
||||
}
|
||||
|
||||
webview {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: 150ms opacity ease;
|
||||
|
||||
&.active {
|
||||
opacity: 1;
|
||||
pointer-events: all;
|
||||
}
|
||||
}
|
||||
|
||||
.logo-fill {
|
||||
fill: #2A2E37;
|
||||
}
|
||||
|
||||
.main {
|
||||
& > .header {
|
||||
width: 100%;
|
||||
height: 71px;
|
||||
border-bottom: 1px solid rgba(117, 122, 131, 0.1);
|
||||
display: flex;
|
||||
margin-bottom: 60px;
|
||||
|
||||
.logo {
|
||||
max-height: fit-content;
|
||||
width: 145px;
|
||||
}
|
||||
|
||||
.shrinker {
|
||||
max-width: 1145px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
max-width: 960px;
|
||||
width: 100%;
|
||||
padding-bottom: 100px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.servers {
|
||||
color: #2B343B;
|
||||
|
||||
& > .header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding-bottom: 21px;
|
||||
|
||||
h3 {
|
||||
font-size: 24px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.35px;
|
||||
line-height: 33px;
|
||||
margin: 0;
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.add-server {
|
||||
margin-left: auto;
|
||||
border-radius: 24px;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
letter-spacing: 1.25px;
|
||||
}
|
||||
|
||||
.refresh {
|
||||
margin-left: 16px;
|
||||
margin-right: 15px;
|
||||
cursor: pointer;
|
||||
|
||||
svg {
|
||||
@keyframes rotate {
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
&.refreshing {
|
||||
animation: rotate 1s linear infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > .grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1.6fr 1.3fr 1.1fr 0.6fr 0.4fr;
|
||||
box-shadow: 0 18px 80px 10px rgba(69, 65, 78, 0.08);
|
||||
border-radius: 0 0 5px 5px;
|
||||
|
||||
.mdc-linear-progress {
|
||||
grid-column-start: 1;
|
||||
grid-column-end: 7;
|
||||
// height: 0;
|
||||
position: relative;
|
||||
--mdc-theme-primary: rgb(107, 109, 102);
|
||||
height: 5px;
|
||||
|
||||
&:after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: #2A2E37;
|
||||
transition: 500ms opacity ease;
|
||||
content: " ";
|
||||
}
|
||||
|
||||
&.loading {
|
||||
&:after {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.title, .value {
|
||||
padding-top: 14px;
|
||||
padding-bottom: 14px;
|
||||
}
|
||||
|
||||
.title {
|
||||
background-color: var(--mdc-theme-primary);
|
||||
font-size: 10px;
|
||||
color: #9D9FA4;
|
||||
font-weight: bold;
|
||||
letter-spacing: 2px;
|
||||
line-height: 12px;
|
||||
text-transform: uppercase;
|
||||
// padding-top: 15px;
|
||||
// padding-bottom: 10px;
|
||||
|
||||
&:first-child {
|
||||
padding-left: 30px;
|
||||
border-radius: 10px 0 0 0;
|
||||
}
|
||||
|
||||
&:nth-child(6) {
|
||||
padding-right: 30px;
|
||||
border-radius: 0 10px 0 0;
|
||||
}
|
||||
|
||||
&.servername {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.value {
|
||||
border-top: 1px solid #EBEBF2;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #717680;
|
||||
background-color: white;
|
||||
|
||||
&.dark {
|
||||
background-color: #F6F8FB;
|
||||
}
|
||||
|
||||
&.servername {
|
||||
.logo {
|
||||
height: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
&.strong {
|
||||
font-weight: 600;
|
||||
color: #2B343B;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.6px;
|
||||
}
|
||||
|
||||
&.status {
|
||||
padding-left: 36px;
|
||||
|
||||
span {
|
||||
margin-left: 7px;
|
||||
line-height: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
&.buttons {
|
||||
button {
|
||||
margin-left: auto;
|
||||
border-radius: 24px;
|
||||
border: 1px solid #CFD1D7;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
letter-spacing: 1.25px;
|
||||
line-height: 16px;
|
||||
padding-left: 18px;
|
||||
padding-right: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
&.icons {
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom-right-radius: 5px;
|
||||
}
|
||||
|
||||
&:nth-last-child(6) {
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.floater {
|
||||
box-shadow: 0 8px 80px 10px rgba(69, 65, 78, 0.08);
|
||||
border-radius: 10px;
|
||||
padding: 3em;
|
||||
min-width: 300px;
|
||||
width: 100%;
|
||||
|
||||
& > h1 {
|
||||
font-size: 3.5em;
|
||||
margin-top: 0px;
|
||||
|
||||
// margin-bottom: 0px;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.mdc-ripple-upgraded--unbounded {
|
||||
padding: 2px;
|
||||
padding-top: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
//@ts-ignore
|
||||
import { MDCTextField } from "@material/textfield";
|
||||
import { TcpHost } from "./connection";
|
||||
import { StorageProvider } from "./storage";
|
||||
import "material-components-web/dist/material-components-web.css";
|
||||
import "./app.scss";
|
||||
import "./tooltip.scss";
|
||||
|
||||
import * as React from "react";
|
||||
import { render } from "react-dom";
|
||||
import { Main } from "./containers";
|
||||
|
||||
export * from "./connection";
|
||||
export interface App {
|
||||
readonly tcp: TcpHost;
|
||||
readonly storage: StorageProvider;
|
||||
readonly node: HTMLElement;
|
||||
}
|
||||
|
||||
export interface RegisteredServer {
|
||||
readonly host: "coder" | "self";
|
||||
readonly hostname: string;
|
||||
readonly name: string;
|
||||
}
|
||||
|
||||
export const create = async (app: App): Promise<void> => {
|
||||
let servers = await app.storage.get<RegisteredServer[]>("servers");
|
||||
if (!servers) {
|
||||
servers = [];
|
||||
}
|
||||
|
||||
render(<Main />, app.node);
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
import { Event } from "@coder/events";
|
||||
import { TunnelCloseEvent } from "@coder/tunnel/src/client";
|
||||
|
||||
export interface TcpHost {
|
||||
listen(host: string, port: number): Promise<TcpServer>;
|
||||
}
|
||||
|
||||
export interface TcpServer {
|
||||
readonly onConnection: Event<TcpConnection>;
|
||||
close(): Promise<void>;
|
||||
}
|
||||
|
||||
export interface TcpConnection {
|
||||
readonly onData: Event<ArrayBuffer>;
|
||||
send(data: ArrayBuffer): Promise<void>;
|
||||
close(): Promise<void>;
|
||||
}
|
||||
@@ -1,573 +0,0 @@
|
||||
//@ts-ignore
|
||||
import { MDCRipple } from "@material/ripple";
|
||||
//@ts-ignore
|
||||
import { MDCTextField } from "@material/textfield";
|
||||
//@ts-ignore
|
||||
import { MDCLinearProgress } from "@material/linear-progress";
|
||||
import * as React from "react";
|
||||
import * as ReactDOM from "react-dom";
|
||||
import { RegisteredServer } from "./app";
|
||||
|
||||
// tslint:disable-next-line:no-any
|
||||
declare var WebSettings: any;
|
||||
|
||||
interface AuthedUser {
|
||||
readonly username: string;
|
||||
}
|
||||
|
||||
export class Main extends React.Component<void, {
|
||||
readonly view: "servers" | "add-server";
|
||||
readonly loading: boolean;
|
||||
}> {
|
||||
private webview: HTMLWebViewElement | undefined;
|
||||
|
||||
public constructor(props: void) {
|
||||
super(props);
|
||||
this.state = {
|
||||
view: "servers",
|
||||
loading: false,
|
||||
};
|
||||
}
|
||||
|
||||
public componentDidMount(): void {
|
||||
window.addEventListener("message", (event) => {
|
||||
if (event.data === "back") {
|
||||
if (this.webview) {
|
||||
this.webview.classList.remove("active");
|
||||
}
|
||||
}
|
||||
if (event.data === "loaded") {
|
||||
if (this.webview) {
|
||||
// this.setState({ loading: false });
|
||||
// this.webview.classList.add("active");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (this.webview) {
|
||||
this.webview.addEventListener("error", (event) => {
|
||||
console.error(event);
|
||||
});
|
||||
this.webview.addEventListener("loadstart", (event) => {
|
||||
this.setState({ loading: true });
|
||||
});
|
||||
this.webview.addEventListener("loadstop", (event) => {
|
||||
this.setState({ loading: false });
|
||||
this.webview!.classList.add("active");
|
||||
// tslint:disable-next-line:no-any
|
||||
const cw = (this.webview as any).contentWindow as Window;
|
||||
cw.postMessage("app", "*");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<div className="main">
|
||||
<div className="header">
|
||||
<div className="shrinker">
|
||||
<Logo />
|
||||
</div>
|
||||
</div>
|
||||
<div className="content">
|
||||
{((): JSX.Element => {
|
||||
switch (this.state.view) {
|
||||
case "servers":
|
||||
return (
|
||||
<Servers servers={[
|
||||
{
|
||||
host: "coder",
|
||||
hostname: "--",
|
||||
name: "Coder",
|
||||
},
|
||||
{
|
||||
host: "self",
|
||||
hostname: "http://localhost:8080",
|
||||
name: "Dev Server",
|
||||
},
|
||||
]}
|
||||
user={{
|
||||
username: "Kyle",
|
||||
}}
|
||||
onSelect={(server): void => {
|
||||
if (this.webview) {
|
||||
this.webview.setAttribute("src", server.hostname);
|
||||
}
|
||||
}}
|
||||
onAddServer={() => this.setState({ view: "add-server" })}
|
||||
loading={this.state.loading}
|
||||
/>
|
||||
);
|
||||
case "add-server":
|
||||
return (
|
||||
<div>Add server</div>
|
||||
);
|
||||
}
|
||||
})()}
|
||||
</div>
|
||||
<webview ref={(wv: HTMLWebViewElement): HTMLWebViewElement => this.webview = wv}></webview>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class AddServer extends React.Component {
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<div className="add-server">
|
||||
<h3>Add Server</h3>
|
||||
<p>Something about what you can do once you add your own server. A link to setup guides for this would be great as well.</p>
|
||||
<Input label="Address" id="address" />
|
||||
<br></br>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class Servers extends React.Component<{
|
||||
readonly user?: AuthedUser;
|
||||
readonly servers: ReadonlyArray<RegisteredServer>;
|
||||
readonly onSelect: (server: RegisteredServer) => void;
|
||||
readonly onAddServer: () => void;
|
||||
readonly loading: boolean;
|
||||
}, {
|
||||
readonly refreshing: boolean;
|
||||
}> {
|
||||
// tslint:disable-next-line:no-any
|
||||
public constructor(props: any) {
|
||||
super(props);
|
||||
this.state = {
|
||||
refreshing: false,
|
||||
};
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<div className="servers">
|
||||
<div className="header">
|
||||
<h3>Servers</h3>
|
||||
<Button onClick={(): void => this.props.onAddServer()} className="add-server" type="unelevated">Add Server</Button>
|
||||
<Ripple>
|
||||
<div className="refresh">
|
||||
<svg onClick={(): void => this.doRefresh()} className={this.state.refreshing ? "refreshing" : ""} width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink">
|
||||
<g stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
|
||||
<g>
|
||||
<g transform="translate(4.000000, 4.000000)" fill="#2A2E37">
|
||||
<path d="M8,3 C9.179,3 10.311,3.423 11.205,4.17 L8.883,6.492 L15.094,7.031 L14.555,0.82 L12.625,2.75 C11.353,1.632 9.71,1 8,1 C4.567,1 1.664,3.454 1.097,6.834 L3.07,7.165 C3.474,4.752 5.548,3 8,3 Z" id="Path"></path>
|
||||
<path d="M8,13 C6.821,13 5.689,12.577 4.795,11.83 L7.117,9.508 L0.906,8.969 L1.445,15.18 L3.375,13.25 C4.647,14.368 6.29,15 8,15 C11.433,15 14.336,12.546 14.903,9.166 L12.93,8.835 C12.526,11.248 10.452,13 8,13 Z" id="Path"></path>
|
||||
</g>
|
||||
<rect id="Rectangle" fillRule="nonzero" x="0" y="0" width="24" height="24"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</Ripple>
|
||||
</div>
|
||||
<div className="grid">
|
||||
<div className="title status">
|
||||
Status
|
||||
</div>
|
||||
<div className="title servername">
|
||||
Server Name
|
||||
</div>
|
||||
<div className="title hostname">
|
||||
Hostname
|
||||
</div>
|
||||
<div className="title details">
|
||||
Details
|
||||
</div>
|
||||
<div className="title">
|
||||
{/* Used for continue/launch buttons */}
|
||||
</div>
|
||||
<div className="title">
|
||||
{/* Used for logout and delete buttons */}
|
||||
</div>
|
||||
|
||||
<div role="progressbar" className={`mdc-linear-progress mdc-linear-progress--indeterminate ${this.props.loading ? "loading" : ""}`} ref={(d) => {
|
||||
if (d) new MDCLinearProgress(d)}}>
|
||||
<div className="mdc-linear-progress__buffering-dots"></div>
|
||||
<div className="mdc-linear-progress__buffer"></div>
|
||||
<div className="mdc-linear-progress__bar mdc-linear-progress__primary-bar">
|
||||
<span className="mdc-linear-progress__bar-inner"></span>
|
||||
</div>
|
||||
<div className="mdc-linear-progress__bar mdc-linear-progress__secondary-bar">
|
||||
<span className="mdc-linear-progress__bar-inner"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{this.props.servers.map((server, i) => {
|
||||
return (
|
||||
<Server key={server.hostname + i} user={this.props.user} server={server} onSelect={(): void => this.props.onSelect(server)} />
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private doRefresh(): void {
|
||||
if (this.state.refreshing) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
refreshing: true,
|
||||
}, () => {
|
||||
setTimeout(() => {
|
||||
this.setState({
|
||||
refreshing: false,
|
||||
});
|
||||
}, 1500);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
interface ServerProps {
|
||||
readonly user?: AuthedUser;
|
||||
readonly server: RegisteredServer;
|
||||
readonly onSelect: () => void;
|
||||
}
|
||||
|
||||
export class Server extends React.Component<ServerProps, {
|
||||
readonly user?: AuthedUser;
|
||||
readonly status: "Online" | "Offline" | "Checking";
|
||||
readonly version: string;
|
||||
}> {
|
||||
// tslint:disable-next-line:no-any
|
||||
public constructor(props: ServerProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
status: props.server.host === "coder" ? "Online" : "Checking",
|
||||
version: "",
|
||||
};
|
||||
}
|
||||
|
||||
public componentWillMount(): void {
|
||||
if (this.props.server.host !== "self") {
|
||||
return;
|
||||
}
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", this.props.server.hostname);
|
||||
xhr.addEventListener("error", (err) => {
|
||||
this.setState({
|
||||
status: "Offline",
|
||||
});
|
||||
});
|
||||
xhr.addEventListener("loadend", () => {
|
||||
if (xhr.status === 200) {
|
||||
this.setState({
|
||||
status: "Online",
|
||||
version: process.env.VERSION,
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
status: "Offline",
|
||||
});
|
||||
}
|
||||
});
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<div className={`status value ${this.extraClasses}`}>
|
||||
{((): JSX.Element => {
|
||||
switch (this.state.status) {
|
||||
case "Offline":
|
||||
return (
|
||||
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink">
|
||||
<g id="Artboard-Copy-3" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
|
||||
<circle id="Oval" stroke="#2B343B" strokeWidth="1.5" fillRule="nonzero" cx="8" cy="8" r="7.25"></circle>
|
||||
<path d="M5.15444712,5.15444712 L10.8455529,10.8455529" id="Path-4" stroke="#2B343B" strokeWidth="1.5" fillRule="nonzero"></path>
|
||||
<path d="M5.15444712,5.15444712 L10.8455529,10.8455529" id="Path-4" stroke="#2B343B" strokeWidth="1.5" fillRule="nonzero" transform="translate(8.000000, 8.000000) scale(-1, 1) translate(-8.000000, -8.000000) "></path>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
case "Online":
|
||||
return (
|
||||
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink">
|
||||
<g id="Artboard-Copy-4" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
|
||||
<g id="checkmark-copy-21" fillRule="nonzero">
|
||||
<circle id="Oval" fill="#2B343B" cx="8" cy="8" r="8"></circle>
|
||||
<polyline id="Path-2" stroke="#FFFFFF" strokeWidth="1.5" points="3.46296296 8.62222222 6.05555556 11.1111111 12.537037 4.88888889"></polyline>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
case "Checking":
|
||||
return (
|
||||
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink">
|
||||
<g id="Artboard-Copy-5" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
|
||||
<circle id="Oval" stroke="#2B343B" strokeWidth="1.5" fillRule="nonzero" cx="8" cy="8" r="7.25"></circle>
|
||||
<polyline id="Path" stroke="#2B343B" strokeWidth="1.5" points="7.90558664 4.63916767 7.90558664 8.63916767 11.9055866 8.63916767"></polyline>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
default:
|
||||
throw new Error("unsupported status");
|
||||
}
|
||||
})()}
|
||||
<span>
|
||||
{this.state.status}
|
||||
</span>
|
||||
</div>
|
||||
<div className={`servername value strong ${this.extraClasses}`}>
|
||||
{this.props.server.host === "coder" ? (
|
||||
<Logo />
|
||||
) : this.props.server.name}
|
||||
</div>
|
||||
<div className={`hostname value ${this.extraClasses}`}>
|
||||
{this.props.server.hostname}
|
||||
</div>
|
||||
<div className={`details value ${this.extraClasses}`}>
|
||||
{this.props.server.host === "coder" && this.props.user ? `Logged in as ${this.props.user.username}` : this.state.version}
|
||||
</div>
|
||||
<div className={`buttons value ${this.extraClasses}`}>
|
||||
<Button onClick={(): void => this.props.onSelect()} className="add-server" type="outlined">{this.props.server.host === "coder" ? "Continue" : "Launch"}</Button>
|
||||
</div>
|
||||
<div className={`icons value ${this.extraClasses}`}>
|
||||
<Ripple>
|
||||
<div>
|
||||
{this.props.server.host === "coder" ? (
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink">
|
||||
<g id="Artboard" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
|
||||
<g id="log-out-copy-2" transform="translate(4.000000, 4.000000)" fill="#2A2E37">
|
||||
<polygon id="Path" points="4 4 0 8 4 12 4 9 10 9 10 7 4 7"></polygon>
|
||||
<path d="M15,16 L6,16 C5.4,16 5,15.6 5,15 L5,12 L7,12 L7,14 L14,14 L14,2 L7,2 L7,4 L5,4 L5,1 C5,0.4 5.4,0 6,0 L15,0 C15.6,0 16,0.4 16,1 L16,15 C16,15.6 15.6,16 15,16 Z" id="Path"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
) : (
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink">
|
||||
<g id="Artboard" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
|
||||
<g id="bin" transform="translate(4.000000, 4.000000)" fill="#2B343B">
|
||||
<rect id="Rectangle" x="5" y="7" width="2" height="6"></rect>
|
||||
<rect id="Rectangle" x="9" y="7" width="2" height="6"></rect>
|
||||
<path d="M12,1 C12,0.4 11.6,0 11,0 L5,0 C4.4,0 4,0.4 4,1 L4,3 L0,3 L0,5 L1,5 L1,15 C1,15.6 1.4,16 2,16 L14,16 C14.6,16 15,15.6 15,15 L15,5 L16,5 L16,3 L12,3 L12,1 Z M6,2 L10,2 L10,3 L6,3 L6,2 Z M13,5 L13,14 L3,14 L3,5 L13,5 Z" id="Shape" fillRule="nonzero"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
)}
|
||||
</div>
|
||||
</Ripple>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
private get extraClasses(): string {
|
||||
return this.props.server.host === "coder" ? "dark" : "";
|
||||
}
|
||||
}
|
||||
|
||||
export class Input extends React.Component<{
|
||||
readonly label: string;
|
||||
readonly id: string;
|
||||
readonly type?: string;
|
||||
}> {
|
||||
private wrapper: HTMLDivElement | undefined;
|
||||
|
||||
public componentDidMount(): void {
|
||||
if (this.wrapper) {
|
||||
const textInput = new MDCTextField(this.wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<div className="mdc-text-field mdc-text-field--outlined" ref={(i: HTMLDivElement): HTMLDivElement => this.wrapper = i}>
|
||||
<input type={this.props.type || "text"} id={this.props.id} className="mdc-text-field__input" spellCheck={false}></input>
|
||||
<div className="mdc-notched-outline">
|
||||
<div className="mdc-notched-outline__leading"></div>
|
||||
<div className="mdc-notched-outline__notch">
|
||||
<label htmlFor={this.props.id} className="mdc-floating-label">{this.props.label}</label>
|
||||
</div>
|
||||
<div className="mdc-notched-outline__trailing"></div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class Button extends React.Component<{
|
||||
readonly type: "outlined" | "unelevated";
|
||||
readonly className?: string;
|
||||
readonly onClick?: () => void;
|
||||
}> {
|
||||
private button: HTMLButtonElement | undefined;
|
||||
|
||||
public componentDidMount(): void {
|
||||
if (this.button) {
|
||||
const b = new MDCRipple(this.button);
|
||||
}
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<button onClick={() => this.props.onClick ? this.props.onClick() : undefined} className={`mdc-button mdc-button--${this.props.type} ${this.props.className || ""}`} ref={(b: HTMLButtonElement): HTMLButtonElement => this.button = b}>
|
||||
<span className="mdc-button__label">{this.props.children}</span>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class Tooltip extends React.Component<{
|
||||
readonly message: string;
|
||||
}> {
|
||||
public componentDidMount(): void {
|
||||
Object.keys(this.refs).forEach((ref) => {
|
||||
const el = this.refs[ref];
|
||||
if (el) {
|
||||
const element = ReactDOM.findDOMNode(el);
|
||||
if (element) {
|
||||
const te = document.createElement("div");
|
||||
te.className = "md-tooltip-content";
|
||||
te.innerHTML = this.props.message;
|
||||
element.appendChild(te);
|
||||
(element as HTMLElement).classList.add("md-tooltip");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<>
|
||||
{React.Children.map(this.props.children, (element, idx) => {
|
||||
return React.cloneElement(element as any, { ref: idx });
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class Ripple extends React.Component<{
|
||||
readonly className?: string;
|
||||
}> {
|
||||
public componentDidMount(): void {
|
||||
Object.keys(this.refs).forEach((ref) => {
|
||||
const el = this.refs[ref];
|
||||
if (el) {
|
||||
const element = ReactDOM.findDOMNode(el);
|
||||
if (element) {
|
||||
(element as HTMLElement).classList.add("mdc-ripple-surface");
|
||||
(element as HTMLElement).setAttribute("data-mdc-ripple-is-unbounded", "");
|
||||
const r = new MDCRipple(element);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<>
|
||||
{React.Children.map(this.props.children, (element, idx) => {
|
||||
return React.cloneElement(element as any, { ref: idx });
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class Logo extends React.Component {
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<svg className="logo" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 471 117"
|
||||
style={{enableBackground: "new 0 0 471 117"} as any} xmlSpace="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<path className="logo-fill" d="M217,75.6c5.9,0,10.7-2.3,14.5-7l7.7,7.9c-6.1,6.9-13.3,10.3-21.6,10.3s-15.1-2.6-20.5-7.9
|
||||
C191.7,73.7,189,67,189,59s2.7-14.7,8.2-20s12.2-8,20.1-8c8.8,0,16.2,3.4,22.2,10.1l-7.5,8.5c-3.8-4.7-8.5-7.1-14.2-7.1
|
||||
c-4.5,0-8.4,1.5-11.6,4.4c-3.2,3-4.8,6.9-4.8,11.9s1.5,9,4.5,12.1C209,74.1,212.6,75.6,217,75.6z M284.1,46.7
|
||||
c-3.1-3.4-6.9-5.1-11.4-5.1s-8.3,1.7-11.4,5.1s-4.6,7.5-4.6,12.3s1.5,8.9,4.6,12.3s6.9,5,11.4,5s8.3-1.7,11.4-5
|
||||
c3.1-3.4,4.6-7.5,4.6-12.3S287.2,50.1,284.1,46.7z M272.7,86.8c-8,0-14.7-2.7-20.1-8s-8.2-11.9-8.2-19.9c0-7.9,2.7-14.5,8.2-19.9
|
||||
c5.4-5.3,12.2-8,20.1-8c8,0,14.7,2.7,20.1,8s8.2,11.9,8.2,19.9c0,7.9-2.7,14.5-8.2,19.9C287.4,84.1,280.7,86.8,272.7,86.8z
|
||||
M352.3,39.4c5.1,4.7,7.7,11.2,7.7,19.6s-2.5,15-7.5,19.9s-12.7,7.3-22.9,7.3h-18.4V32.3h19C339.8,32.4,347.2,34.7,352.3,39.4z
|
||||
M343.5,71.5c3-2.8,4.4-6.8,4.4-12.1s-1.5-9.4-4.4-12.2c-3-2.9-7.5-4.3-13.6-4.3h-6.7v32.8h7.6C336.3,75.6,340.5,74.2,343.5,71.5z
|
||||
M409.3,32.4v10.7h-26.8v11.1h24.1v10.3h-24.1v11.2h27.7v10.6h-39.7V32.4H409.3L409.3,32.4z M464.6,50.3c0,8.6-3.4,14.2-10.3,16.7
|
||||
l13.6,19.3h-14.8l-11.9-17.2h-8.3v17.2h-12V32.4h20.4c8.4,0,14.4,1.4,17.9,4.2C462.8,39.4,464.6,44,464.6,50.3z M450.1,56.7
|
||||
c1.5-1.3,2.2-3.5,2.2-6.4s-0.8-4.9-2.3-6s-4.2-1.6-8.1-1.6h-9v16h8.8C445.8,58.7,448.6,58,450.1,56.7z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path className="logo-fill" d="M164.8,50.9c-3.3,0-5.5-1.9-5.5-5.8V22.7c0-14.3-6-22.2-21.5-22.2h-7.2v15.1h2.2c6.1,0,9,3.3,9,9.2v19.8
|
||||
c0,8.6,2.6,12.1,8.3,13.9c-5.7,1.7-8.3,5.3-8.3,13.9c0,4.9,0,9.8,0,14.7c0,4.1,0,8.1-1.1,12.2c-1.1,3.8-2.9,7.4-5.4,10.5
|
||||
c-1.4,1.8-3,3.3-4.8,4.7v2h7.2c15.5,0,21.5-7.9,21.5-22.2V71.9c0-4,2.1-5.8,5.5-5.8h4.1V51h-4V50.9L164.8,50.9z"/>
|
||||
<path className="logo-fill" d="M115.8,23.3H93.6c-0.5,0-0.9-0.4-0.9-0.9v-1.7c0-0.5,0.4-0.9,0.9-0.9h22.3c0.5,0,0.9,0.4,0.9,0.9v1.7
|
||||
C116.8,22.9,116.3,23.3,115.8,23.3z"/>
|
||||
<path className="logo-fill" d="M119.6,44.9h-16.2c-0.5,0-0.9-0.4-0.9-0.9v-1.7c0-0.5,0.4-0.9,0.9-0.9h16.2c0.5,0,0.9,0.4,0.9,0.9V44
|
||||
C120.5,44.4,120.1,44.9,119.6,44.9z"/>
|
||||
<path className="logo-fill" d="M126,34.1H93.6c-0.5,0-0.9-0.4-0.9-0.9v-1.7c0-0.5,0.4-0.9,0.9-0.9h32.3c0.5,0,0.9,0.4,0.9,0.9v1.7
|
||||
C126.8,33.6,126.5,34.1,126,34.1z"/>
|
||||
<g>
|
||||
<path className="logo-fill" d="M67.9,28.2c2.2,0,4.4,0.2,6.5,0.7v-4.1c0-5.8,3-9.2,9-9.2h2.2V0.5h-7.2c-15.5,0-21.5,7.9-21.5,22.2v7.4
|
||||
C60.4,28.9,64.1,28.2,67.9,28.2z"/>
|
||||
</g>
|
||||
<path className="logo-fill" d="M132.8,82.6c-1.6-12.7-11.4-23.3-24-25.7c-3.5-0.7-7-0.8-10.4-0.2c-0.1,0-0.1-0.1-0.2-0.1
|
||||
c-5.5-11.5-17.3-19.1-30.1-19.1S43.6,44.9,38,56.4c-0.1,0-0.1,0.1-0.2,0.1c-3.6-0.4-7.2-0.2-10.8,0.7c-12.4,3-21.8,13.4-23.5,26
|
||||
c-0.2,1.3-0.3,2.6-0.3,3.8c0,3.8,2.6,7.3,6.4,7.8c4.7,0.7,8.8-2.9,8.7-7.5c0-0.7,0-1.5,0.1-2.2c0.8-6.4,5.7-11.8,12.1-13.3
|
||||
c2-0.5,4-0.6,5.9-0.3c6.1,0.8,12.1-2.3,14.7-7.7c1.9-4,4.9-7.5,8.9-9.4c4.4-2.1,9.4-2.4,14-0.8c4.8,1.7,8.4,5.3,10.6,9.8
|
||||
c2.3,4.4,3.4,7.5,8.3,8.1c2,0.3,7.6,0.2,9.7,0.1c4.1,0,8.2,1.4,11.1,4.3c1.9,2,3.3,4.5,3.9,7.3c0.9,4.5-0.2,9-2.9,12.4
|
||||
c-1.9,2.4-4.5,4.2-7.4,5c-1.4,0.4-2.8,0.5-4.2,0.5c-0.8,0-1.9,0-3.2,0c-4,0-12.5,0-18.9,0c-4.4,0-7.9-3.5-7.9-7.9V78.4V63.9
|
||||
c0-1.2-1-2.2-2.2-2.2h-3.1c-6.1,0.1-11,6.9-11,14.1s0,26.3,0,26.3c0,7.8,6.3,14.1,14.1,14.1c0,0,34.7-0.1,35.2-0.1
|
||||
c8-0.8,15.4-4.9,20.4-11.2C131.5,98.8,133.8,90.8,132.8,82.6z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// const $ = <K extends keyof HTMLElementTagNameMap>(tagName: K, className?: string, content?: string): HTMLElementTagNameMap[K] => {
|
||||
// const el = document.createElement(tagName);
|
||||
// if (className) {
|
||||
// el.className = className;
|
||||
// }
|
||||
// if (content) {
|
||||
// el.innerText = content;
|
||||
// }
|
||||
|
||||
// return el;
|
||||
// };
|
||||
|
||||
// const createInput = (id: string, labelName: string, type: string = "text"): HTMLDivElement => {
|
||||
// // <div class="mdc-text-field mdc-text-field--outlined">
|
||||
// // <input type="password" id="password" class="mdc-text-field__input">
|
||||
// // <!-- <label class="mdc-floating-label" for="name">Name</label>
|
||||
// // <div class="mdc-line-ripple"></div> -->
|
||||
// // <div class="mdc-notched-outline">
|
||||
// // <div class="mdc-notched-outline__leading"></div>
|
||||
// // <div class="mdc-notched-outline__notch">
|
||||
// // <label for="password" class="mdc-floating-label">Password</label>
|
||||
// // </div>
|
||||
// // <div class="mdc-notched-outline__trailing"></div>
|
||||
// // </div>
|
||||
|
||||
// const wrapper = $("div", "mdc-text-field mdc-text-field--outlined");
|
||||
// const input = $("input", "mdc-text-field__input");
|
||||
// input.type = type;
|
||||
// input.id = id;
|
||||
// wrapper.appendChild(input);
|
||||
// const notchedOutline = $("div", "mdc-notched-outline");
|
||||
// notchedOutline.appendChild($("div", "mdc-notched-outline__leading"));
|
||||
// const notch = $("div", "mdc-notched-outline__notch");
|
||||
// const label = $("label", "mdc-floating-label", labelName);
|
||||
// label.setAttribute("for", id);
|
||||
// notch.appendChild(label);
|
||||
// notchedOutline.appendChild(notch);
|
||||
// wrapper.appendChild(notchedOutline);
|
||||
// wrapper.appendChild($("div", "mdc-notched-outline__trailing"));
|
||||
|
||||
// const field = new MDCTextField(wrapper);
|
||||
|
||||
// return wrapper;
|
||||
// };
|
||||
|
||||
// export const createCoderLogin = (parentNode: HTMLElement): void => {
|
||||
// parentNode.appendChild($("h1", "header", "Login with Coder"));
|
||||
// parentNode.appendChild(createInput("username", "Username"));
|
||||
// parentNode.appendChild($("br"));
|
||||
// parentNode.appendChild($("br"));
|
||||
// parentNode.appendChild(createInput("password", "Password", "password"));
|
||||
// };
|
||||