Compare commits
508 Commits
1.31.0
...
2.1665-vsc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
6c8e513e71 | ||
|
|
f7c1ebf667 | ||
|
|
ba37a34fa2 | ||
|
|
e1dc6967ed | ||
|
|
3155eb76f5 | ||
|
|
e597d49912 | ||
|
|
0a9f5d8eee | ||
|
|
736feaba51 | ||
|
|
307aa4ae7f | ||
|
|
1df352fe26 | ||
|
|
8aff206538 | ||
|
|
03c0bde3a9 | ||
|
|
a36476df21 | ||
|
|
25c46bea32 | ||
|
|
60937c604e | ||
|
|
449d51d24d | ||
|
|
26edea5098 | ||
|
|
8527d10033 | ||
|
|
4387fdfb9e | ||
|
|
41d1be9205 | ||
|
|
76e0338d7f | ||
|
|
f37533579d | ||
|
|
438808573d | ||
|
|
c471babc69 | ||
|
|
d7a66e4f15 | ||
|
|
30d14eeab4 | ||
|
|
e22e2c8b67 | ||
|
|
ffb75b6801 | ||
|
|
cded51f650 | ||
|
|
8bab787804 | ||
|
|
3e9d86ee91 | ||
|
|
e418ecf653 | ||
|
|
36c05ed335 | ||
|
|
5c435a3b6c | ||
|
|
9f4212eace | ||
|
|
96175d36ea | ||
|
|
c8afb7908e | ||
|
|
231cdec7fb | ||
|
|
8e5f288459 | ||
|
|
14f1230bed | ||
|
|
fba3fe5609 | ||
|
|
8e68411174 | ||
|
|
3d654a8df7 | ||
|
|
87d2e22a6b | ||
|
|
17267bd801 | ||
|
|
ac56fcaafc | ||
|
|
e20b79b5cc | ||
|
|
e99f8abc3c | ||
|
|
994531d8bb | ||
|
|
8916cb9bb2 | ||
|
|
d4867ca430 | ||
|
|
3fbdb2e46c | ||
|
|
1d8da2161f | ||
|
|
414eb7076f | ||
|
|
2b3d2933eb | ||
|
|
14ead1a62f | ||
|
|
3b48c57861 | ||
|
|
c772e920cd | ||
|
|
e6aa74c412 | ||
|
|
838c8a6f2c | ||
|
|
4028e33529 | ||
|
|
ec94a92a5f | ||
|
|
379a5243fe | ||
|
|
47765dde23 | ||
|
|
d48d72cb79 | ||
|
|
31518e9754 | ||
|
|
1e0d330778 | ||
|
|
ef6369d62f | ||
|
|
5b0d11e470 |
12
.dockerignore
Normal file
@@ -0,0 +1,12 @@
|
||||
Dockerfile
|
||||
build
|
||||
deployment
|
||||
doc
|
||||
.github
|
||||
.gitignore
|
||||
.node-version
|
||||
.travis.yml
|
||||
LICENSE
|
||||
README.md
|
||||
node_modules
|
||||
release
|
||||
3
.github/CODEOWNERS
vendored
@@ -1 +1,2 @@
|
||||
* @coderasher @kylecarbs
|
||||
* @code-asher @kylecarbs
|
||||
Dockerfile @nhooyr
|
||||
|
||||
14
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -2,17 +2,21 @@
|
||||
name: Bug Report
|
||||
about: Report problems and unexpected behavior.
|
||||
title: ''
|
||||
labels: ''
|
||||
labels: 'bug'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
<!-- Please search existing issues to avoid creating duplicates. -->
|
||||
<!-- All extension-specific issues should be created with the `Extension Bug` template. -->
|
||||
|
||||
- `vscode-remote` version: <!-- The version of vscode-remote -->
|
||||
- `code-server` version: <!-- The version of code-server -->
|
||||
- OS Version: <!-- OS version, cloud provider, -->
|
||||
|
||||
#### Steps to Reproduce
|
||||
## Description
|
||||
|
||||
1.
|
||||
2.
|
||||
<!-- Describes the problem here -->
|
||||
|
||||
## Steps to Reproduce
|
||||
|
||||
1. <!-- step 1: click ... -->
|
||||
1. <!-- step 2: ... -->
|
||||
12
.github/ISSUE_TEMPLATE/extension_bug.md
vendored
@@ -8,11 +8,15 @@ assignees: ''
|
||||
|
||||
<!-- Please search existing issues to avoid creating duplicates. -->
|
||||
|
||||
- `vscode-remote` version: <!-- The version of vscode-remote -->
|
||||
- `code-server` version: <!-- The version of code-server -->
|
||||
- OS Version: <!-- OS version, cloud provider, -->
|
||||
- Extension: <!-- Link to extension -->
|
||||
|
||||
#### Steps to Reproduce
|
||||
## Description
|
||||
|
||||
1.
|
||||
2.
|
||||
<!-- Describes the problem here -->
|
||||
|
||||
## Steps to Reproduce
|
||||
|
||||
1. <!-- step 1: click ... -->
|
||||
1. <!-- step 2: ... -->
|
||||
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -2,7 +2,7 @@
|
||||
name: Feature Request
|
||||
about: Suggest an idea for this project.
|
||||
title: ''
|
||||
labels: ''
|
||||
labels: 'feature'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
|
||||
6
.github/ISSUE_TEMPLATE/question.md
vendored
@@ -2,16 +2,16 @@
|
||||
name: Question
|
||||
about: Ask a question.
|
||||
title: ''
|
||||
labels: ''
|
||||
labels: 'question'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
<!-- Please search existing issues to avoid creating duplicates. -->
|
||||
|
||||
#### Description
|
||||
## Description
|
||||
|
||||
<!-- A description of the the question. -->
|
||||
|
||||
#### Related Issues
|
||||
## Related Issues
|
||||
|
||||
<!-- Any issues related to your question. -->
|
||||
6
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<!-- 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?
|
||||
|
||||
8
.gitignore
vendored
@@ -1,5 +1,5 @@
|
||||
lib
|
||||
node_modules
|
||||
dist
|
||||
out
|
||||
.DS_Store
|
||||
build
|
||||
release
|
||||
binaries
|
||||
source
|
||||
|
||||
1
.node-version
Normal file
@@ -0,0 +1 @@
|
||||
10.16.0
|
||||
100
.travis.yml
@@ -1,33 +1,73 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 8.9.3
|
||||
filter_secrets: false
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: ubuntu
|
||||
- os: osx
|
||||
- 10.16.0
|
||||
services:
|
||||
- docker
|
||||
|
||||
before_install:
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install libxkbfile-dev libsecret-1-dev;
|
||||
fi
|
||||
script:
|
||||
- scripts/build.sh
|
||||
# before_deploy:
|
||||
# - export TRAVIS_TAG="1.0.$TRAVIS_BUILD_NUMBER"
|
||||
# - echo "$TRAVIS_TAG" "$TRAVIS_COMMIT"
|
||||
# - git config --local user.name "$USER_NAME"
|
||||
# - git config --local user.email "$USER_EMAIL"
|
||||
# - git tag "$TRAVIS_TAG" "$TRAVIS_COMMIT"
|
||||
# deploy:
|
||||
# provider: releases
|
||||
# tag_name: $TRAVIS_TAG
|
||||
# target_commitish: $TRAVIS_COMMIT
|
||||
# name: $TRAVIS_TAG
|
||||
# skip_cleanup: true
|
||||
# api_key:
|
||||
# secure: T/yqCIeqLifteriv8D3CnehNFzSBP309GZqeUfyx8Q+xSQEttA9Enxl+Qw9GkdedYTN4J56iucHIac6CwcvKSKIXqk80CeSEW0BNxZs5wIgv4rRMMy/GAX0NBWKNOkoGlH8M6VyQcM7eY2iGAn1EX755PHalk6rWwfsauRANOQyb2DXQBan5C0YUnogq2qcW1xkIwlXH7l0Ekbtego0f6QPv0rSyOcL1LKm6xk0Aq+xLNKJkT6TSL6xYpkPlZLjnql09Nspkqs6NehWlft2n09bHqAtjNnWw9OYCvxp8mdHeTE5uShuEqYPzdYU5LVFoE7wElI8uqS66noaA18ytZYGw2IrY6GZcn+wtR6WyM2+YXl2HclL1/Fs6Vn8+zwq2IBZchBNv3KJSn1dxiqLlD/s6YQyni17x/9FhtFoNUvsbY5zSC1xrnNQBQWFg0TRnoC9rPR+7hQtT1+5+CvRxpvcNWnPuA22919PFE79ejJulPmsnyF+YLs9c6APJgOpOO1f6fKt5Mcb02dubPqGcQ9NbqUUNTl4IUvEtjG0LnFAgEGerxAcsdnUTxzBVf0LJLlhRKW1BigUTbRwfUJL1DN0mWg9cg7fL5VqrogvNq3uRguxOsYr+bcHDbimQSAY3No3fAkTTqQSJh56Dx57/Un18KxuOTiRB9de1RtiudsI=
|
||||
# file_glob: true
|
||||
# file: packages/server/cli-*
|
||||
# on:
|
||||
# repo: codercom/code-server
|
||||
# branch: master
|
||||
- export MAJOR_VERSION="2"
|
||||
- export VSCODE_VERSION="1.39.2"
|
||||
- export VERSION="$MAJOR_VERSION.$TRAVIS_BUILD_NUMBER"
|
||||
- export TAG="$VERSION-vsc$VSCODE_VERSION"
|
||||
- if [[ "$TRAVIS_BRANCH" == "master" ]]; then export MINIFY="true"; fi
|
||||
- if [[ "$TRAVIS_BRANCH" == "master" ]]; then export PACKAGE="true"; fi
|
||||
|
||||
# Don't build on tags because we'll already have built the commit.
|
||||
jobs:
|
||||
include:
|
||||
- name: "Linux build"
|
||||
os: linux
|
||||
dist: trusty
|
||||
env: TARGET="linux" PUSH_DOCKER="true"
|
||||
if: tag IS blank
|
||||
script: scripts/ci.bash
|
||||
- name: "Alpine build"
|
||||
os: linux
|
||||
dist: trusty
|
||||
env: TARGET="alpine"
|
||||
if: tag IS blank
|
||||
script: scripts/ci.bash
|
||||
- name: "MacOS build"
|
||||
os: osx
|
||||
if: tag IS blank
|
||||
script: travis_wait 60 scripts/ci.bash
|
||||
|
||||
git:
|
||||
depth: 3
|
||||
|
||||
before_deploy:
|
||||
- echo "$TAG" "$TRAVIS_COMMIT"
|
||||
- git config --local user.name "$USER_NAME"
|
||||
- git config --local user.email "$USER_EMAIL"
|
||||
- if ! git tag "$TAG" "$TRAVIS_COMMIT" ; then echo "$TAG already exists"; fi
|
||||
- if [[ -n "$PUSH_DOCKER" ]] ; then echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin ; fi
|
||||
|
||||
deploy:
|
||||
- provider: releases
|
||||
file_glob: true
|
||||
draft: true
|
||||
tag_name: "$TAG"
|
||||
target_commitish: "$TRAVIS_COMMIT"
|
||||
name: "$TAG"
|
||||
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: cdr/code-server
|
||||
branch: master
|
||||
|
||||
- provider: script
|
||||
skip_cleanup: true
|
||||
script: docker build -f ./scripts/ci.dockerfile -t codercom/code-server:"$TAG" -t codercom/code-server:v2 -t codercom/code-server . && docker push codercom/code-server:"$TAG" && docker push codercom/code-server:v2 && docker push codercom/code-server
|
||||
on:
|
||||
repo: cdr/code-server
|
||||
branch: master
|
||||
condition: -n "$PUSH_DOCKER"
|
||||
|
||||
cache:
|
||||
yarn: true
|
||||
directories:
|
||||
- source
|
||||
|
||||
61
Dockerfile
Normal file
@@ -0,0 +1,61 @@
|
||||
FROM node:10.16.0
|
||||
ARG codeServerVersion=docker
|
||||
ARG vscodeVersion
|
||||
ARG githubToken
|
||||
|
||||
# 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 . .
|
||||
|
||||
RUN yarn \
|
||||
&& MINIFY=true GITHUB_TOKEN="${githubToken}" yarn build "${vscodeVersion}" "${codeServerVersion}" \
|
||||
&& yarn binary "${vscodeVersion}" "${codeServerVersion}" \
|
||||
&& mv "/src/binaries/code-server${codeServerVersion}-vsc${vscodeVersion}-linux-x86_64" /src/binaries/code-server \
|
||||
&& rm -r /src/build \
|
||||
&& rm -r /src/source
|
||||
|
||||
# We deploy with ubuntu so that devs have a familiar environment.
|
||||
FROM ubuntu:18.04
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
openssl \
|
||||
net-tools \
|
||||
git \
|
||||
locales \
|
||||
sudo \
|
||||
dumb-init \
|
||||
vim \
|
||||
curl \
|
||||
wget
|
||||
|
||||
RUN locale-gen en_US.UTF-8
|
||||
# We 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 LC_ALL=en_US.UTF-8 \
|
||||
SHELL=/bin/bash
|
||||
|
||||
RUN adduser --gecos '' --disabled-password coder && \
|
||||
echo "coder ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/nopasswd
|
||||
|
||||
USER coder
|
||||
# We create first instead of just using WORKDIR as when WORKDIR creates, the
|
||||
# user is root.
|
||||
RUN mkdir -p /home/coder/project
|
||||
|
||||
WORKDIR /home/coder/project
|
||||
|
||||
# This ensures we have a volume mounted even if the user forgot to do bind
|
||||
# mount. So that they do not lose their data if they delete the container.
|
||||
VOLUME [ "/home/coder/project" ]
|
||||
|
||||
COPY --from=0 /src/binaries/code-server /usr/local/bin/code-server
|
||||
EXPOSE 8080
|
||||
|
||||
ENTRYPOINT ["dumb-init", "code-server", "--host", "0.0.0.0"]
|
||||
193
README.md
@@ -1,49 +1,188 @@
|
||||
# code-server
|
||||
# code-server · [](https://github.com/cdr/code-server/blob/master/LICENSE) [](https://github.com/cdr/code-server/releases/latest) [](https://github.com/cdr/code-server)
|
||||
|
||||
[](https://github.com/codercom/code-server/issues)
|
||||
[](https://github.com/codercom/code-server/releases/latest)
|
||||
[](#)
|
||||
`code-server` is [VS Code](https://github.com/Microsoft/vscode) running on a
|
||||
remote server, accessible through the browser.
|
||||
|
||||
`code-server` is VS Code running on a remote server, accessible through the browser.
|
||||
Try it out:
|
||||
|
||||

|
||||
```bash
|
||||
docker run -it -p 127.0.0.1:8080:8080 -v "${HOME}/.local/share/code-server:/home/coder/.local/share/code-server" -v "$PWD:/home/coder/project" codercom/code-server:v2
|
||||
```
|
||||
|
||||
- **Consistent environment:** Code on your Chromebook, tablet, and laptop with a
|
||||
consistent dev environment. develop more easily for Linux if you have a
|
||||
Windows or Mac, and pick up where you left off when switching workstations.
|
||||
- **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 computation runs on your server.
|
||||
|
||||

|
||||
|
||||
## Getting Started
|
||||
|
||||
[Try `code-server` now](https://coder.com/signup) for free at coder.com.
|
||||
### Requirements
|
||||
|
||||
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
|
||||
- 64-bit host.
|
||||
- At least 1GB of RAM.
|
||||
- 2 cores or more are recommended (1 core works but not optimally).
|
||||
- Secure connection over HTTPS or localhost (required for service workers).
|
||||
- For Linux: GLIBC 2.17 or later and GLIBCXX 3.4.15 or later.
|
||||
- Docker (for Docker versions of `code-server`).
|
||||
|
||||
```
|
||||
code-server <inital directory to open>
|
||||
```
|
||||
> You will be prompted to enter the password shown in the CLI
|
||||
`code-server` should now be running at https://<IP>:8443.
|
||||
### Run over SSH
|
||||
|
||||
> 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.
|
||||
Use [sshcode](https://github.com/codercom/sshcode) for a simple setup.
|
||||
|
||||
For detailed instructions and troubleshooting, see the [self-hosted quick start guide](doc/self-hosted/index.md).
|
||||
### Docker
|
||||
|
||||
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).
|
||||
See the Docker one-liner mentioned above. Dockerfile is at [/Dockerfile](/Dockerfile).
|
||||
|
||||
How to [secure your setup](/doc/security/ssl.md).
|
||||
To debug Golang using the
|
||||
[ms-vscode-go extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.Go),
|
||||
you need to add `--security-opt seccomp=unconfined` to your `docker run`
|
||||
arguments when launching code-server with Docker. See
|
||||
[#725](https://github.com/cdr/code-server/issues/725) for details.
|
||||
|
||||
## Development
|
||||
### Digital Ocean
|
||||
|
||||
### Known Issues
|
||||
[](https://marketplace.digitalocean.com/apps/code-server?action=deploy)
|
||||
|
||||
- Debugging extensions doesn’t work.
|
||||
### Binaries
|
||||
|
||||
### Future
|
||||
1. [Download a binary](https://github.com/cdr/code-server/releases). (Linux and
|
||||
OS X supported. Windows coming soon)
|
||||
2. Unpack the downloaded file then run the binary.
|
||||
3. In your browser navigate to `localhost:8080`.
|
||||
|
||||
- For self-hosting and other information see [doc/quickstart.md](doc/quickstart.md).
|
||||
- For hosting on cloud platforms see [doc/deploy.md](doc/deploy.md).
|
||||
|
||||
### Build
|
||||
|
||||
See
|
||||
[VS Code prerequisites](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#prerequisites)
|
||||
before building.
|
||||
|
||||
```shell
|
||||
export OUT=/path/to/output/build # Optional if only building. Required if also developing.
|
||||
yarn build ${vscodeVersion} ${codeServerVersion} # See travis.yml for the VS Code version to use.
|
||||
# The code-server version can be anything you want.
|
||||
node ~/path/to/output/build/out/vs/server/main.js # You can run the built JavaScript with Node.
|
||||
yarn binary ${vscodeVersion} ${codeServerVersion} # Or you can package it into a binary.
|
||||
```
|
||||
|
||||
## Security
|
||||
|
||||
### Authentication
|
||||
By default `code-server` enables password authentication using a randomly
|
||||
generated password. You can set the `PASSWORD` environment variable to use your
|
||||
own instead or use `--auth none` to disable password authentication.
|
||||
|
||||
Do not expose `code-server` to the open internet without some form of
|
||||
authentication.
|
||||
|
||||
### Encrypting traffic with HTTPS
|
||||
If you aren't doing SSL termination elsewhere you can directly give
|
||||
`code-server` a certificate with `code-server --cert` followed by the path to
|
||||
your certificate. Additionally, you can use certificate keys with `--cert-key`
|
||||
followed by the path to your key. If you pass `--cert` without any path
|
||||
`code-server` will generate a self-signed certificate.
|
||||
|
||||
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.
|
||||
|
||||
Do not expose `code-server` to the open internet without SSL, whether built-in
|
||||
or through a proxy.
|
||||
|
||||
## Known Issues
|
||||
|
||||
- Creating custom VS Code extensions and debugging them doesn't work.
|
||||
- Extension profiling and tips are currently disabled.
|
||||
|
||||
## Future
|
||||
|
||||
- **Stay up to date!** Get notified about new releases of code-server.
|
||||

|
||||
- Windows support.
|
||||
- Electron and ChromeOS applications to bridge the gap between local<->remote.
|
||||
- Electron and Chrome OS applications to bridge the gap between local<->remote.
|
||||
- Run VS Code unit tests against our builds to ensure features work as expected.
|
||||
|
||||
## Extensions
|
||||
|
||||
code-server does not provide access to the official
|
||||
[Visual Studio Marketplace](https://marketplace.visualstudio.com/vscode). Instead,
|
||||
Coder has created a custom extension marketplace that we manage for open-source
|
||||
extensions. If you want to use an extension with code-server that we do not have
|
||||
in our marketplace please look for a release in the extension’s repository,
|
||||
contact us to see if we have one in the works or, if you build an extension
|
||||
locally from open source, you can copy it to the `extensions` folder. If you
|
||||
build one locally from open-source please contribute it to the project and let
|
||||
us know so we can give you props! If you have your own custom marketplace, it is
|
||||
possible to point code-server to it by setting the `SERVICE_URL` and `ITEM_URL`
|
||||
environment variables.
|
||||
|
||||
## Telemetry
|
||||
|
||||
Use the `--disable-telemetry` flag to completely disable telemetry. We use the
|
||||
data collected to improve code-server.
|
||||
|
||||
## Contributing
|
||||
|
||||
Guides on setup for development will be coming soon. :)
|
||||
### Development
|
||||
|
||||
See
|
||||
[VS Code prerequisites](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#prerequisites)
|
||||
before developing.
|
||||
|
||||
```shell
|
||||
git clone https://github.com/microsoft/vscode
|
||||
cd vscode
|
||||
git checkout ${vscodeVersion} # See travis.yml for the version to use.
|
||||
yarn
|
||||
git clone https://github.com/cdr/code-server src/vs/server
|
||||
cd src/vs/server
|
||||
yarn
|
||||
yarn patch:apply
|
||||
yarn watch
|
||||
# Wait for the initial compilation to complete (it will say "Finished compilation").
|
||||
# Run the next command in another shell.
|
||||
yarn start
|
||||
# Visit http://localhost:8080
|
||||
```
|
||||
|
||||
If you run into issues about a different version of Node being used, try running
|
||||
`npm rebuild` in the VS Code directory and ignore the error at the end from
|
||||
`vscode-ripgrep`.
|
||||
|
||||
### Upgrading VS Code
|
||||
|
||||
We patch VS Code to provide and fix some functionality. 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, **stage all the changes** you want to be included in
|
||||
the patch in the VS Code source, then run `yarn patch:generate` in this
|
||||
directory.
|
||||
|
||||
Our changes include:
|
||||
|
||||
- Change the remote schema to `code-server`.
|
||||
- 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.
|
||||
- Add an upload service along with a file prefix to ignore for temporary files
|
||||
created during upload.
|
||||
- Make changing the display language work.
|
||||
- Make it possible for us to load code on the client.
|
||||
- Make extensions work in the browser.
|
||||
- Fix getting permanently disconnected when you sleep or hibernate for a while.
|
||||
- Make it possible to automatically update the binary.
|
||||
|
||||
## License
|
||||
|
||||
@@ -51,8 +190,10 @@ Guides on setup for development will be coming soon. :)
|
||||
|
||||
## Enterprise
|
||||
|
||||
Visit [our enterprise page](https://coder.com/enterprise) for more information on our enterprise offering.
|
||||
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.
|
||||
If you would like to commercialize code-server, please contact
|
||||
contact@coder.com.
|
||||
|
||||
263
build/tasks.ts
@@ -1,263 +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 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") {
|
||||
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)) {
|
||||
/**
|
||||
* We create a binary with nexe
|
||||
* so we can compress it
|
||||
*/
|
||||
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]);
|
||||
}
|
||||
if (fs.statSync(targetBinaryPath).size >= 20000000) {
|
||||
// Compress w/ upx
|
||||
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"]);
|
||||
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"]);
|
||||
if (clone.exitCode !== 0) {
|
||||
throw new Error(`Failed to clone: ${clone.exitCode}`);
|
||||
}
|
||||
}
|
||||
|
||||
runner.cwd = vscodePath;
|
||||
const checkout = await runner.execute("git", ["checkout", "tags/1.31.0"]);
|
||||
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 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}`);
|
||||
}
|
||||
});
|
||||
|
||||
run();
|
||||
@@ -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/cros.png
Normal file
|
After Width: | Height: | Size: 121 KiB |
24
doc/assets/droplet.svg
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="200px" height="40px" viewBox="0 0 200 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.5 (67469) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>do-btn-blue-ghost</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Partner-welcome-kit-Copy-3" transform="translate(-651.000000, -828.000000)">
|
||||
<g id="do-btn-blue-ghost" transform="translate(651.000000, 828.000000)">
|
||||
<rect id="Rectangle-Copy-4" stroke="#0069FF" x="0.5" y="0.5" width="199" height="39" rx="6"></rect>
|
||||
<path d="M6,0 L47,0 L47,40 L6,40 C2.6862915,40 4.05812251e-16,37.3137085 0,34 L-8.8817842e-16,6 C-1.29399067e-15,2.6862915 2.6862915,6.08718376e-16 6,0 Z" id="Rectangle-Copy-5" fill="#0069FF"></path>
|
||||
<g id="DO_Logo_horizontal_blue-Copy-3" transform="translate(13.000000, 10.000000)" fill="#FFFFFF">
|
||||
<path d="M10.0098493,20 L10.0098493,16.1262429 C14.12457,16.1262429 17.2897398,12.0548452 15.7269372,7.74627862 C15.1334679,6.14538921 13.8674,4.86072487 12.2650328,4.28756693 C7.952489,2.72620566 3.87733294,5.88845634 3.87733294,9.99938223 C3.87733294,9.99938223 3.87733294,9.99938223 3.87733294,9.99938223 L0,9.99938223 C0,3.45747613 6.3303395,-1.64165309 13.1948014,0.492866119 C16.2017127,1.42177726 18.57559,3.81322933 19.5053586,6.79760341 C21.6418482,13.6754986 16.5577943,20 10.0098493,20 Z" id="XMLID_49_"></path>
|
||||
<polygon id="XMLID_47_" points="9.52380952 16.1904762 5.71428571 16.1904762 5.71428571 12.3809524 5.71428571 12.3809524 9.52380952 12.3809524 9.52380952 12.3809524"></polygon>
|
||||
<polygon id="XMLID_46_" points="6.66666667 19.047619 3.80952381 19.047619 3.80952381 19.047619 3.80952381 16.1904762 6.66666667 16.1904762"></polygon>
|
||||
<polygon id="XMLID_45_" points="3.80952381 16.1904762 0.952380952 16.1904762 0.952380952 16.1904762 0.952380952 13.3333333 0.952380952 13.3333333 3.80952381 13.3333333 3.80952381 13.3333333"></polygon>
|
||||
</g>
|
||||
<!-- Modified to add GitHub font-family after DigitalOcean's font-family, otherwise it looks bad on GitHub -->
|
||||
<text id="Create-a-Droplet-Copy-3" font-family="Sailec-Medium, Sailec, -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol" font-size="16" font-weight="400" fill="#0069FF">
|
||||
<tspan x="58" y="26">Create a Droplet</tspan>
|
||||
</text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
BIN
doc/assets/ide.gif
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
|
Before Width: | Height: | Size: 984 KiB |
|
Before Width: | Height: | Size: 22 KiB |
BIN
doc/assets/release.gif
Normal file
|
After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 97 KiB |
75
doc/cros-install.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Installing code-server in your ChromiumOS/ChromeOS/CloudReady machine
|
||||
|
||||
This guide will show you how to install code-server into your CrOS machine.
|
||||
|
||||
## Using Crostini
|
||||
|
||||
One of the easier ways to run code-server is via
|
||||
[Crostini](https://www.aboutchromebooks.com/tag/project-crostini/), the Linux
|
||||
apps support feature in CrOS. Make sure you have enough RAM, HDD space and your
|
||||
CPU has VT-x/ AMD-V support. If your chromebook has this, then you are
|
||||
qualified to use Crostini.
|
||||
|
||||
If you are running R69, you might want to enable this on
|
||||
[Chrome Flags](chrome://flags/#enable-experimental-crostini-ui).
|
||||
If you run R72, however, this is already enabled for you.
|
||||
|
||||
After checking your prerequisites, follow the steps in [the self-host install guide](index.md)
|
||||
on installing code-server. Once done, make sure code-server works by running
|
||||
it. After running it, simply go to `penguin.linux.test:8080` to access
|
||||
code-server. Now you should be greeted with this screen. If you did,
|
||||
congratulations, you have installed code-server in your Chromebook!
|
||||
|
||||

|
||||
|
||||
Alternatively, if you ran code-server in another container and you need the IP
|
||||
for that specific container, simply go to Termina's shell via `crosh` and type
|
||||
`vsh termina`.
|
||||
|
||||
```bash
|
||||
Loading extra module: /usr/share/crosh/dev.d/50-crosh.sh
|
||||
Welcome to crosh, the Chrome OS developer shell.
|
||||
|
||||
If you got here by mistake, don't panic! Just close this tab and carry on.
|
||||
|
||||
Type 'help' for a list of commands.
|
||||
|
||||
If you want to customize the look/behavior, you can use the options page.
|
||||
Load it by using the Ctrl+Shift+P keyboard shortcut.
|
||||
|
||||
crosh> vsh termina
|
||||
(termina) chronos@localhost ~ $
|
||||
```
|
||||
While in termina, run `lxc list`. It should output the list of running containers.
|
||||
|
||||
```bash
|
||||
(termina) chronos@localhost ~ $ lxc list
|
||||
+---------|---------|-----------------------|------|------------|-----------+
|
||||
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
|
||||
+---------|---------|-----------------------|------|------------|-----------+
|
||||
| penguin | RUNNING | 100.115.92.199 (eth0) | | PERSISTENT | 0 |
|
||||
+---------|---------|-----------------------|------|------------|-----------+
|
||||
(termina) chronos@localhost ~ $
|
||||
```
|
||||
|
||||
For this example, we show the default `penguin` container, which is exposed on
|
||||
`eth0` at 100.115.92.199. Simply enter the IP of the container where the
|
||||
code-server runs to Chrome.
|
||||
|
||||
## Using Crouton
|
||||
|
||||
[Crouton](https://github.com/dnschneid/crouton) is one of the old ways to get a
|
||||
running full Linux via `chroot` on a Chromebook. To use crouton, enable
|
||||
developer mode and go to `crosh`. This time, run `shell`, which should drop you
|
||||
to `bash`.
|
||||
|
||||
Make sure you downloaded `crouton`, if so, go ahead and run it under
|
||||
`~/Downloads`. After installing your chroot container via crouton, go ahead and
|
||||
enter `enter-chroot` to enter your container.
|
||||
|
||||
Follow the instructions set in [the self-host install guide](index.md) to
|
||||
install code-server. After that is done, run `code-server` and verify it works
|
||||
by going to `localhost:8080`.
|
||||
|
||||
> At this point in writing, `localhost` seems to work in this method. However,
|
||||
> the author is not sure if it applies still to newer Chromebooks.
|
||||
73
doc/deploy.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Set up instance
|
||||
## EC2 on AWS
|
||||
- Click **Launch Instance** from your [EC2 dashboard](https://console.aws.amazon.com/ec2/v2/home).
|
||||
- Select the Ubuntu Server 18.04 LTS (HVM), SSD Volume Type
|
||||
- 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 a **Custom TCP Rule** rule with port range set to `8080` and source
|
||||
set to "Anywhere".
|
||||
> 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.
|
||||
- From the dropdown choose "create a new pair", give the key pair a name.
|
||||
- Click **Download Key Pair** and store the file in a safe place.
|
||||
- Click **Launch Instances**.
|
||||
- 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 SSH into your instance:
|
||||
```
|
||||
ssh -i ${path to key pair} ubuntu@${public address}
|
||||
```
|
||||
|
||||
## DigitalOcean
|
||||
[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:
|
||||
```
|
||||
ssh root@${instance ip}
|
||||
```
|
||||
|
||||
## Google Cloud
|
||||
> Pre-requisite: Set up the [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.
|
||||
- Expand the "Management, security, disks, networking, sole tenancy" section,
|
||||
go to the "Networking" tab, then under network tags add "code-server".
|
||||
- Create your VM, and **take note** of its public IP address.
|
||||
- Visit "VPC network" in the console and go to "Firewall rules". Create a new
|
||||
firewall rule called "http-8080". Under "Target tags" add "code-server", and
|
||||
under "Protocols and ports" tick "Specified protocols and ports" and "tcp".
|
||||
Beside "tcp", add "8080", then create the rule.
|
||||
- Open a terminal on your computer and SSH into your Google Cloud VM:
|
||||
```
|
||||
gcloud compute ssh --zone ${region} ${instance name}
|
||||
```
|
||||
# Run code-server
|
||||
- Download the latest code-server release from the
|
||||
[releases page](https://github.com/cdr/code-server/releases/latest)
|
||||
to the instance, extract the file, then run the code-server binary:
|
||||
```
|
||||
wget https://github.com/cdr/code-server/releases/download/{version}/code-server{version}-linux-x64.tar.gz
|
||||
tar -xvzf code-server{version}-linux-x64.tar.gz
|
||||
cd code-server{version}-linux-x64
|
||||
./code-server
|
||||
```
|
||||
- Open your browser and visit http://$public_ip:8080/ where `$public_ip` is
|
||||
your instance's public IP address.
|
||||
- For long-term use, set up a systemd service to run code-server.
|
||||
15
doc/examples/fail2ban.conf
Normal file
@@ -0,0 +1,15 @@
|
||||
# Fail2Ban filter for code-server
|
||||
|
||||
[Definition]
|
||||
|
||||
failregex = ^INFO\s+Failed login attempt\s+{\"password\":\"(\\.|[^"])*\",\"remoteAddress\":\"<HOST>\"
|
||||
|
||||
# Use this instead for proxies (ensure the proxy is configured to send the
|
||||
# X-Forwarded-For header).
|
||||
# failregex = ^INFO\s+Failed login attempt\s+{\"password\":\"(\\.|[^"])*\",\"xForwardedFor\":\"<HOST>\"
|
||||
|
||||
ignoreregex =
|
||||
|
||||
datepattern = "timestamp":{EPOCH}}$
|
||||
|
||||
# Author: Dean Sheather
|
||||
73
doc/examples/kubernetes.aws.yaml
Normal file
@@ -0,0 +1,73 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: code-server
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: code-server
|
||||
namespace: code-server
|
||||
spec:
|
||||
ports:
|
||||
- port: 8080
|
||||
name: https
|
||||
protocol: TCP
|
||||
selector:
|
||||
app: code-server
|
||||
type: ClusterIP
|
||||
---
|
||||
kind: StorageClass
|
||||
apiVersion: storage.k8s.io/v1
|
||||
metadata:
|
||||
name: gp2
|
||||
annotations:
|
||||
storageclass.kubernetes.io/is-default-class: "true"
|
||||
provisioner: kubernetes.io/aws-ebs
|
||||
parameters:
|
||||
type: gp2
|
||||
fsType: ext4
|
||||
---
|
||||
kind: PersistentVolumeClaim
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: code-store
|
||||
namespace: code-server
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 60Gi
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: code-server
|
||||
name: code-server
|
||||
namespace: code-server
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: code-server
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: code-server
|
||||
spec:
|
||||
containers:
|
||||
- image: codercom/code-server:v2
|
||||
imagePullPolicy: Always
|
||||
name: code-servery
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
name: https
|
||||
volumeMounts:
|
||||
- name: code-server-storage
|
||||
mountPath: /go/src
|
||||
volumes:
|
||||
- name: code-server-storage
|
||||
persistentVolumeClaim:
|
||||
claimName: code-store
|
||||
43
doc/examples/kubernetes.yaml
Normal file
@@ -0,0 +1,43 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: code-server
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: code-server
|
||||
namespace: code-server
|
||||
spec:
|
||||
ports:
|
||||
- port: 8080
|
||||
name: https
|
||||
protocol: TCP
|
||||
selector:
|
||||
app: code-server
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: code-server
|
||||
name: code-server
|
||||
namespace: code-server
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: code-server
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: code-server
|
||||
spec:
|
||||
containers:
|
||||
- image: codercom/code-server:v2
|
||||
imagePullPolicy: Always
|
||||
name: code-server
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
name: https
|
||||
35
doc/fail2ban.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Protecting code-server from bruteforce attempts
|
||||
code-server outputs all failed login attempts, along with the IP address,
|
||||
provided password, user agent and timestamp by default.
|
||||
|
||||
When using a reverse proxy such as Nginx or Apache, the remote address may
|
||||
appear to be `127.0.0.1` or a similar address so `X-Forwarded-For` should be
|
||||
used instead. Ensure that you are setting this value in your reverse proxy:
|
||||
|
||||
Nginx:
|
||||
```
|
||||
location / {
|
||||
...
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Apache:
|
||||
```
|
||||
<VirtualEnv>
|
||||
...
|
||||
SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded
|
||||
...
|
||||
</VirtualEnv>
|
||||
```
|
||||
|
||||
It is extremely important that you ensure that your code-server instance is not
|
||||
accessible from the internet (use localhost or block it in your firewall).
|
||||
|
||||
## Fail2Ban
|
||||
Fail2Ban allows for automatically banning and logging repeated failed
|
||||
authentication attempts for many applications through regex filters. A working
|
||||
filter for code-server can be found in `./code-server.fail2ban.conf`. Once this
|
||||
is installed and configured correctly, repeated failed login attempts should
|
||||
automatically be banned from connecting to your server.
|
||||
98
doc/quickstart.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# Quickstart Guide
|
||||
1. Visit the [releases page](https://github.com/cdr/code-server/releases) and
|
||||
download the latest binary for your operating system.
|
||||
2. Unpack the downloaded file then run the binary.
|
||||
3. In your browser navigate to `localhost:8080`.
|
||||
|
||||
## Usage
|
||||
Run `code-server --help` to view available options.
|
||||
|
||||
### Nginx Reverse Proxy
|
||||
The trailing slashes are important.
|
||||
|
||||
```
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name code.example.com code.example.org;
|
||||
location /some/path/ { # Or / if hosting at the root.
|
||||
proxy_pass http://localhost:8080/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection upgrade;
|
||||
proxy_set_header Accept-Encoding gzip;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Apache Reverse Proxy
|
||||
```
|
||||
<VirtualHost *:80>
|
||||
ServerName code.example.com
|
||||
|
||||
RewriteEngine On
|
||||
RewriteCond %{HTTP:Upgrade} =websocket [NC]
|
||||
RewriteRule /(.*) ws://localhost:8080/$1 [P,L]
|
||||
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
|
||||
RewriteRule /(.*) http://localhost:8080/$1 [P,L]
|
||||
|
||||
ProxyRequests off
|
||||
ProxyPass / http://localhost:8080/ nocanon
|
||||
ProxyPassReverse / http://localhost:8080/
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
### Run automatically at startup
|
||||
|
||||
In some cases you might need to run code-server automatically once the host starts. You may use your local init service to do so.
|
||||
|
||||
#### Systemd
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Code Server IDE
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=<USER>
|
||||
EnvironmentFile=$HOME/.profile
|
||||
WorkingDirectory=$HOME
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
|
||||
ExecStart=<PATH TO BINARY> $(pwd)
|
||||
|
||||
StandardOutput=file:/var/log/code-server-output.log
|
||||
StandardError=file:/var/log/code-server-error.log
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
#### OpenRC
|
||||
|
||||
```sh
|
||||
#!/sbin/openrc-run
|
||||
|
||||
depend() {
|
||||
after net-online
|
||||
need net
|
||||
}
|
||||
|
||||
supervisor=supervise-daemon
|
||||
name="code-server"
|
||||
command="/opt/cdr/code-server"
|
||||
command_args=""
|
||||
|
||||
pidfile="/var/run/cdr.pid"
|
||||
respawn_delay=5
|
||||
|
||||
set -o allexport
|
||||
if [ -f /etc/environment ]; then source /etc/environment; fi
|
||||
set +o allexport
|
||||
```
|
||||
|
||||
#### Kubernetes/Docker
|
||||
|
||||
Make sure you set your restart policy to always - this will ensure your container starts as the daemon starts.
|
||||
@@ -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 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,75 +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 `8080` 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:8080`
|
||||
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: 8080] Port to bind on
|
||||
-v, --version show CLI version
|
||||
--cert=cert
|
||||
--cert-key=cert-key
|
||||
--help show CLI help
|
||||
```
|
||||
|
||||
### 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 it's 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 `8080` as it's 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)
|
||||
|
||||
### 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.
|
||||
13
docker-compose.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
code-server:
|
||||
container_name: code-server
|
||||
image: codercom/code-server
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- "${PWD}:/home/coder/project"
|
||||
- "${HOME}/.local/share/code-server:/home/coder/.local/share/code-server"
|
||||
environment:
|
||||
PASSWORD: ${PASSWORD}
|
||||
7
main.js
Normal file
@@ -0,0 +1,7 @@
|
||||
// Once our entry file is loaded we no longer need nbin to bypass normal Node
|
||||
// execution. We can still shim the fs into the binary even when bypassing. This
|
||||
// will ensure for example that a spawn like `${process.argv[0]} -e` will work
|
||||
// while still allowing us to access files within the binary.
|
||||
process.env.NBIN_BYPASS = true;
|
||||
|
||||
require("../../bootstrap-amd").load("vs/server/src/node/cli");
|
||||
80
package.json
@@ -1,57 +1,41 @@
|
||||
{
|
||||
"name": "@coder/code-server",
|
||||
"repository": "https://github.com/codercom/code-server",
|
||||
"author": "Coder",
|
||||
"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"
|
||||
"runner": "cd ./scripts && node --max-old-space-size=32384 -r ts-node/register ./build.ts",
|
||||
"start": "nodemon --watch ../../../out --verbose ../../../out/vs/server/main.js",
|
||||
"watch": "cd ../../../ && yarn watch",
|
||||
"build": "yarn && yarn runner build",
|
||||
"package": "yarn runner package",
|
||||
"binary": "yarn runner binary",
|
||||
"patch:generate": "cd ../../../ && git diff --staged > ./src/vs/server/scripts/vscode.patch",
|
||||
"patch:apply": "cd ../../../ && git apply ./src/vs/server/scripts/vscode.patch"
|
||||
},
|
||||
"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"
|
||||
"@coder/nbin": "^1.2.2",
|
||||
"@types/fs-extra": "^8.0.1",
|
||||
"@types/node": "^10.12.12",
|
||||
"@types/pem": "^1.9.5",
|
||||
"@types/safe-compare": "^1.1.0",
|
||||
"@types/tar-fs": "^1.16.1",
|
||||
"@types/tar-stream": "^1.6.1",
|
||||
"fs-extra": "^8.1.0",
|
||||
"nodemon": "^1.19.1",
|
||||
"ts-node": "^8.4.1",
|
||||
"typescript": "3.6"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/node": "^10.12.12",
|
||||
"safe-buffer": "^5.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-loader": "^0.6.0",
|
||||
"trash": "^4.3.0",
|
||||
"webpack-merge": "^4.2.1"
|
||||
"@coder/logger": "^1.1.8",
|
||||
"@coder/node-browser": "^1.0.6",
|
||||
"@coder/requirefs": "^1.0.6",
|
||||
"httpolyglot": "^0.1.2",
|
||||
"pem": "^1.14.2",
|
||||
"safe-compare": "^1.1.4",
|
||||
"tar-fs": "^2.0.0",
|
||||
"tar-stream": "^2.1.0",
|
||||
"util": "^0.12.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,44 +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>
|
||||
<div class="mdc-text-field-helper-line">
|
||||
<div class="mdc-text-field-helper-text">helper text</div>
|
||||
</div>
|
||||
<div class="mdc-form-field">
|
||||
<div class="mdc-checkbox">
|
||||
<input type="checkbox" class="mdc-checkbox__native-control" id="remember" />
|
||||
<div class="mdc-checkbox__background">
|
||||
<svg class="mdc-checkbox__checkmark" viewBox="0 0 24 24">
|
||||
<path class="mdc-checkbox__checkmark-path" fill="none" d="M1.73,12.91 8.1,19.28 22.79,4.59" />
|
||||
</svg>
|
||||
<div class="mdc-checkbox__mixedmark"></div>
|
||||
</div>
|
||||
</div>
|
||||
<label for="remember">Remember Me</label>
|
||||
</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: "v1.31.0",
|
||||
});
|
||||
} 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"));
|
||||
// };
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
export interface StorageProvider {
|
||||
set<T>(key: string, value: T): Promise<void>;
|
||||
get<T>(key: string): Promise<T | undefined>;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
.md-tooltip {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.md-tooltip-content {
|
||||
position: absolute;
|
||||
bottom: -35px;
|
||||
left: 50%;
|
||||
padding: 7px;
|
||||
transform: translateX(-50%) scale(0);
|
||||
transition: transform 0.15s cubic-bezier(0, 0, 0.2, 1);
|
||||
transform-origin: top;
|
||||
background: rgba(67, 67, 67, 0.97);
|
||||
color: white;
|
||||
letter-spacing: 0.3px;
|
||||
border-radius: 3px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.md-tooltip:hover .md-tooltip-content {
|
||||
transform: translateX(-50%) scale(1);
|
||||
}
|
||||
@@ -1,601 +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/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/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/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/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/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/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/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/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==
|
||||
|
||||
"@types/prop-types@*":
|
||||
version "15.5.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.5.8.tgz#8ae4e0ea205fe95c3901a5a1df7f66495e3a56ce"
|
||||
integrity sha512-3AQoUxQcQtLHsK25wtTWIoIpgYjH3vSDroZOUr7PpCHw/jLY1RB9z9E8dBT/OSmwStVgkRNvdh+ZHNiomRieaw==
|
||||
|
||||
"@types/react-dom@^16.8.0":
|
||||
version "16.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.8.0.tgz#c565f43f9d2ec911f9e0b8f3b74e25e67879aa3f"
|
||||
integrity sha512-Jp4ufcEEjVJEB0OHq2MCZcE1u3KYUKO6WnSuiU/tZeYeiZxUoQavfa/TZeiIT+1XoN6l0lQVNM30VINZFDeolQ==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@^16.8.2":
|
||||
version "16.8.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.8.2.tgz#3b7a7f7ea89d1c7d68b00849fb5de839011c077b"
|
||||
integrity sha512-6mcKsqlqkN9xADrwiUz2gm9Wg4iGnlVGciwBRYFQSMWG6MQjhOZ/AVnxn+6v8nslFgfYTV8fNdE6XwKu6va5PA==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
csstype "^2.2.0"
|
||||
|
||||
csstype@^2.2.0:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.2.tgz#3043d5e065454579afc7478a18de41909c8a2f01"
|
||||
integrity sha512-Rl7PvTae0pflc1YtxtKbiSqq20Ts6vpIYOD5WBafl4y123DyHUeLrRdQP66sQW8/6gmX8jrYJLXwNeMqYVJcow==
|
||||
|
||||
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"
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||
|
||||
loose-envify@^1.1.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||
dependencies:
|
||||
js-tokens "^3.0.0 || ^4.0.0"
|
||||
|
||||
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"
|
||||
|
||||
object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
||||
|
||||
prop-types@^15.6.2:
|
||||
version "15.7.1"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.1.tgz#2fa61e0a699d428b40320127733ee2931f05d9d1"
|
||||
integrity sha512-f8Lku2z9kERjOCcnDOPm68EBJAO2K00Q5mSgPAUE/gJuBgsYLbVy6owSrtcHj90zt8PvW+z0qaIIgsIhHOa1Qw==
|
||||
dependencies:
|
||||
object-assign "^4.1.1"
|
||||
react-is "^16.8.1"
|
||||
|
||||
react-dom@^16.8.1:
|
||||
version "16.8.1"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.1.tgz#ec860f98853d09d39bafd3a6f1e12389d283dbb4"
|
||||
integrity sha512-N74IZUrPt6UiDjXaO7UbDDFXeUXnVhZzeRLy/6iqqN1ipfjrhR60Bp5NuBK+rv3GMdqdIuwIl22u1SYwf330bg==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.2"
|
||||
scheduler "^0.13.1"
|
||||
|
||||
react-is@^16.8.1:
|
||||
version "16.8.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.1.tgz#a80141e246eb894824fb4f2901c0c50ef31d4cdb"
|
||||
integrity sha512-ioMCzVDWvCvKD8eeT+iukyWrBGrA3DiFYkXfBsVYIRdaREZuBjENG+KjrikavCLasozqRWTwFUagU/O4vPpRMA==
|
||||
|
||||
react@^16.8.1:
|
||||
version "16.8.1"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.8.1.tgz#ae11831f6cb2a05d58603a976afc8a558e852c4a"
|
||||
integrity sha512-wLw5CFGPdo7p/AgteFz7GblI2JPOos0+biSoxf1FPsGxWQZdN/pj6oToJs1crn61DL3Ln7mN86uZ4j74p31ELQ==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.2"
|
||||
scheduler "^0.13.1"
|
||||
|
||||
scheduler@^0.13.1:
|
||||
version "0.13.1"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.1.tgz#1a217df1bfaabaf4f1b92a9127d5d732d85a9591"
|
||||
integrity sha512-VJKOkiKIN2/6NOoexuypwSrybx13MY7NSy9RNt8wPvZDMRT1CW6qlpF5jXRToXNHz3uWzbm2elNpZfXfGPqP9A==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
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=
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"name": "@coder/disposable",
|
||||
"main": "src/index.ts"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export interface IDisposable {
|
||||
dispose(): void;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export * from "./disposable";
|
||||
@@ -1,4 +0,0 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
# This file specifies files that are *not* uploaded to Google Cloud Platform
|
||||
# using gcloud. It follows the same syntax as .gitignore, with the addition of
|
||||
# "#!include" directives (which insert the entries of the given .gitignore-style
|
||||
# file at that point).
|
||||
#
|
||||
# For more information, run:
|
||||
# $ gcloud topic gcloudignore
|
||||
#
|
||||
.gcloudignore
|
||||
# If you would like to upload your .git directory, .gitignore file or files
|
||||
# from your .gitignore file, remove the corresponding line
|
||||
# below:
|
||||
.git
|
||||
.gitignore
|
||||
src
|
||||
|
||||
# Node.js dependencies:
|
||||
node_modules/
|
||||
@@ -1,8 +0,0 @@
|
||||
FROM node
|
||||
|
||||
COPY out/main.js /main.js
|
||||
COPY package.json /package.json
|
||||
RUN yarn
|
||||
ENV NODE_ENV production
|
||||
|
||||
CMD ["node", "/main.js"]
|
||||
@@ -1,5 +0,0 @@
|
||||
runtime: nodejs10
|
||||
service: cdrdns
|
||||
network:
|
||||
forwarded_ports:
|
||||
- 53/udp
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"name": "@coder/dns",
|
||||
"main": "out/main.js",
|
||||
"scripts": {
|
||||
"build": "../../node_modules/.bin/webpack --config ./webpack.config.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-named": "^0.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ip-address": "^5.8.9",
|
||||
"@types/ip-address": "^5.8.2"
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
import { field, logger } from "@coder/logger";
|
||||
import * as http from "http";
|
||||
//@ts-ignore
|
||||
import * as named from "node-named";
|
||||
import * as ip from "ip-address";
|
||||
import { words, wordKeys } from "./words";
|
||||
|
||||
import * as dgram from "dgram";
|
||||
|
||||
const oldCreate = dgram.createSocket;
|
||||
|
||||
// tslint:disable-next-line:no-any
|
||||
(<any>dgram).createSocket = (_: any, callback: any): dgram.Socket => {
|
||||
return oldCreate("udp4", callback);
|
||||
};
|
||||
|
||||
interface DnsQuery {
|
||||
name(): string;
|
||||
// tslint:disable-next-line:no-any
|
||||
addAnswer(domain: string, target: any, ttl: number): void;
|
||||
}
|
||||
|
||||
const dnsServer: {
|
||||
listen(port: number, host: string, callback: () => void): void;
|
||||
on(event: "query", callback: (query: DnsQuery) => void): void;
|
||||
send(query: DnsQuery): void;
|
||||
} = named.createServer();
|
||||
|
||||
const isDev = process.env.NODE_ENV !== "production";
|
||||
const dnsPort = isDev ? 9999 : 53;
|
||||
dnsServer.listen(dnsPort, "0.0.0.0", () => {
|
||||
logger.info("DNS server started", field("port", dnsPort));
|
||||
});
|
||||
|
||||
dnsServer.on("query", (query) => {
|
||||
const domain = query.name();
|
||||
const reqParts = domain.split(".");
|
||||
if (reqParts.length < 2) {
|
||||
dnsServer.send(query);
|
||||
logger.info("Invalid request", field("request", domain));
|
||||
|
||||
return;
|
||||
}
|
||||
const allWords = reqParts.shift()!;
|
||||
if (allWords.length > 16) {
|
||||
dnsServer.send(query);
|
||||
logger.info("Invalid request", field("request", domain));
|
||||
|
||||
return;
|
||||
}
|
||||
const wordParts = allWords.split(/(?=[A-Z])/);
|
||||
const ipParts: string[] = [];
|
||||
// Should be left with HowAreYouNow
|
||||
for (let i = 0; i < wordParts.length; i++) {
|
||||
const part = wordParts[i];
|
||||
if (part.length > 4) {
|
||||
dnsServer.send(query);
|
||||
logger.info("Words too long", field("request", domain));
|
||||
|
||||
return;
|
||||
}
|
||||
const ipPart = words[part.toLowerCase()];
|
||||
if (typeof ipPart === "undefined") {
|
||||
dnsServer.send(query);
|
||||
logger.info("Word not found in index", field("part", part), field("request", domain));
|
||||
|
||||
return;
|
||||
}
|
||||
ipParts.push(ipPart.toString());
|
||||
}
|
||||
|
||||
const address = new ip.Address4(ipParts.join("."));
|
||||
|
||||
if (address.isValid()) {
|
||||
logger.info("Responded with valid address query", field("address", address.address), field("request", domain));
|
||||
query.addAnswer(domain, new named.ARecord(address.address), 99999);
|
||||
} else {
|
||||
logger.warn("Received invalid request", field("request", domain));
|
||||
}
|
||||
|
||||
dnsServer.send(query);
|
||||
});
|
||||
|
||||
const httpServer = http.createServer((request, response) => {
|
||||
const remoteAddr = request.connection.remoteAddress;
|
||||
if (!remoteAddr) {
|
||||
response.writeHead(422);
|
||||
response.end();
|
||||
|
||||
return;
|
||||
}
|
||||
const hostHeader = request.headers.host;
|
||||
if (!hostHeader) {
|
||||
response.writeHead(422);
|
||||
response.end();
|
||||
|
||||
return;
|
||||
}
|
||||
const host = remoteAddr.split(".").map(p => wordKeys[Number.parseInt(p, 10)]).map(s => s.charAt(0).toUpperCase() + s.slice(1)).join("");
|
||||
logger.info("Resolved host", field("remote-addr", remoteAddr), field("host", host));
|
||||
response.writeHead(200);
|
||||
response.write(`${host}.${hostHeader}`);
|
||||
response.end();
|
||||
});
|
||||
|
||||
const httpPort = isDev ? 3000 : 80;
|
||||
httpServer.listen(httpPort, "0.0.0.0", () => {
|
||||
logger.info("HTTP server started", field("port", httpPort));
|
||||
});
|
||||
@@ -1,260 +0,0 @@
|
||||
export const words: { readonly [key: string]: number } = {
|
||||
term: 0,
|
||||
salt: 1,
|
||||
barn: 2,
|
||||
corn: 3,
|
||||
went: 4,
|
||||
feel: 5,
|
||||
rest: 6,
|
||||
will: 7,
|
||||
pale: 8,
|
||||
cave: 9,
|
||||
dirt: 10,
|
||||
time: 11,
|
||||
in: 12,
|
||||
pie: 13,
|
||||
star: 14,
|
||||
iron: 15,
|
||||
door: 16,
|
||||
tone: 17,
|
||||
want: 18,
|
||||
task: 19,
|
||||
zoo: 20,
|
||||
nor: 21,
|
||||
fall: 22,
|
||||
tell: 23,
|
||||
noon: 24,
|
||||
new: 25,
|
||||
per: 26,
|
||||
end: 27,
|
||||
arm: 28,
|
||||
been: 29,
|
||||
wolf: 30,
|
||||
port: 31,
|
||||
beat: 32,
|
||||
pour: 33,
|
||||
far: 34,
|
||||
may: 35,
|
||||
tie: 36,
|
||||
moon: 37,
|
||||
duck: 38,
|
||||
us: 39,
|
||||
led: 40,
|
||||
met: 41,
|
||||
bank: 42,
|
||||
day: 43,
|
||||
due: 44,
|
||||
both: 45,
|
||||
pet: 46,
|
||||
gate: 47,
|
||||
pain: 48,
|
||||
rock: 49,
|
||||
fill: 50,
|
||||
open: 51,
|
||||
thus: 52,
|
||||
mark: 53,
|
||||
our: 54,
|
||||
loud: 55,
|
||||
wife: 56,
|
||||
say: 57,
|
||||
flag: 58,
|
||||
as: 59,
|
||||
ride: 60,
|
||||
once: 61,
|
||||
sun: 62,
|
||||
duty: 63,
|
||||
pure: 64,
|
||||
made: 65,
|
||||
gulf: 66,
|
||||
pig: 67,
|
||||
fish: 68,
|
||||
name: 69,
|
||||
army: 70,
|
||||
have: 71,
|
||||
ill: 72,
|
||||
meal: 73,
|
||||
ago: 74,
|
||||
late: 75,
|
||||
view: 76,
|
||||
atom: 77,
|
||||
pen: 78,
|
||||
mud: 79,
|
||||
tail: 80,
|
||||
sink: 81,
|
||||
cow: 82,
|
||||
rear: 83,
|
||||
fur: 84,
|
||||
go: 85,
|
||||
suit: 86,
|
||||
come: 87,
|
||||
fear: 88,
|
||||
also: 89,
|
||||
sail: 90,
|
||||
row: 91,
|
||||
lay: 92,
|
||||
noun: 93,
|
||||
hat: 94,
|
||||
am: 95,
|
||||
mail: 96,
|
||||
keep: 97,
|
||||
drop: 98,
|
||||
than: 99,
|
||||
weak: 100,
|
||||
by: 101,
|
||||
who: 102,
|
||||
fire: 103,
|
||||
good: 104,
|
||||
sick: 105,
|
||||
care: 106,
|
||||
pink: 107,
|
||||
lady: 108,
|
||||
war: 109,
|
||||
sets: 110,
|
||||
swam: 111,
|
||||
well: 112,
|
||||
shoe: 113,
|
||||
bent: 114,
|
||||
fuel: 115,
|
||||
wet: 116,
|
||||
fog: 117,
|
||||
land: 118,
|
||||
lead: 119,
|
||||
tax: 120,
|
||||
deal: 121,
|
||||
verb: 122,
|
||||
take: 123,
|
||||
save: 124,
|
||||
gift: 125,
|
||||
had: 126,
|
||||
gold: 127,
|
||||
slow: 128,
|
||||
drew: 129,
|
||||
lamp: 130,
|
||||
roof: 131,
|
||||
hung: 132,
|
||||
wild: 133,
|
||||
able: 134,
|
||||
girl: 135,
|
||||
warn: 136,
|
||||
were: 137,
|
||||
know: 138,
|
||||
camp: 139,
|
||||
milk: 140,
|
||||
neck: 141,
|
||||
aid: 142,
|
||||
fair: 143,
|
||||
bell: 144,
|
||||
dig: 145,
|
||||
hope: 146,
|
||||
wood: 147,
|
||||
away: 148,
|
||||
cook: 149,
|
||||
just: 150,
|
||||
form: 151,
|
||||
food: 152,
|
||||
hall: 153,
|
||||
mind: 154,
|
||||
for: 155,
|
||||
card: 156,
|
||||
half: 157,
|
||||
sat: 158,
|
||||
now: 159,
|
||||
team: 160,
|
||||
rush: 161,
|
||||
face: 162,
|
||||
wire: 163,
|
||||
such: 164,
|
||||
tool: 165,
|
||||
make: 166,
|
||||
fat: 167,
|
||||
hold: 168,
|
||||
inch: 169,
|
||||
bill: 170,
|
||||
mean: 171,
|
||||
tide: 172,
|
||||
burn: 173,
|
||||
talk: 174,
|
||||
tape: 175,
|
||||
hard: 176,
|
||||
mine: 177,
|
||||
on: 178,
|
||||
year: 179,
|
||||
rich: 180,
|
||||
sum: 181,
|
||||
yes: 182,
|
||||
baby: 183,
|
||||
wide: 184,
|
||||
how: 185,
|
||||
clay: 186,
|
||||
car: 187,
|
||||
here: 188,
|
||||
cent: 189,
|
||||
bowl: 190,
|
||||
post: 191,
|
||||
said: 192,
|
||||
see: 193,
|
||||
raw: 194,
|
||||
foot: 195,
|
||||
life: 196,
|
||||
bar: 197,
|
||||
from: 198,
|
||||
path: 199,
|
||||
meat: 200,
|
||||
show: 201,
|
||||
sent: 202,
|
||||
wait: 203,
|
||||
mice: 204,
|
||||
ten: 205,
|
||||
pot: 206,
|
||||
nice: 207,
|
||||
idea: 208,
|
||||
or: 209,
|
||||
onto: 210,
|
||||
rose: 211,
|
||||
your: 212,
|
||||
this: 213,
|
||||
cat: 214,
|
||||
bet: 215,
|
||||
took: 216,
|
||||
hang: 217,
|
||||
very: 218,
|
||||
bend: 219,
|
||||
mix: 220,
|
||||
base: 221,
|
||||
jack: 222,
|
||||
her: 223,
|
||||
leg: 224,
|
||||
own: 225,
|
||||
book: 226,
|
||||
love: 227,
|
||||
dawn: 228,
|
||||
deer: 229,
|
||||
hit: 230,
|
||||
rain: 231,
|
||||
gas: 232,
|
||||
eat: 233,
|
||||
tube: 234,
|
||||
case: 235,
|
||||
pipe: 236,
|
||||
get: 237,
|
||||
joy: 238,
|
||||
ever: 239,
|
||||
nest: 240,
|
||||
home: 241,
|
||||
egg: 242,
|
||||
pack: 243,
|
||||
hand: 244,
|
||||
cold: 245,
|
||||
hot: 246,
|
||||
frog: 247,
|
||||
peep: 248,
|
||||
seed: 249,
|
||||
rawr: 250,
|
||||
top: 251,
|
||||
meow: 252,
|
||||
bark: 253,
|
||||
eel: 254,
|
||||
swap: 255,
|
||||
};
|
||||
|
||||
export const wordKeys = Object.keys(words);
|
||||
@@ -1,21 +0,0 @@
|
||||
const path = require("path");
|
||||
const merge = require("webpack-merge");
|
||||
|
||||
const root = path.resolve(__dirname, "../..");
|
||||
|
||||
module.exports = merge(
|
||||
require(path.join(root, "scripts/webpack.node.config.js"))({
|
||||
// Options.
|
||||
}), {
|
||||
externals: {
|
||||
"node-named": "commonjs node-named",
|
||||
},
|
||||
output: {
|
||||
path: path.join(__dirname, "out"),
|
||||
filename: "main.js",
|
||||
},
|
||||
entry: [
|
||||
"./packages/dns/src/dns.ts"
|
||||
],
|
||||
},
|
||||
);
|
||||
@@ -1,88 +0,0 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/ip-address@^5.8.2":
|
||||
version "5.8.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/ip-address/-/ip-address-5.8.2.tgz#5e413c477f78b3a264745eac937538a6e6e0c1f6"
|
||||
integrity sha512-LFlDGRjJDnahfPyNCZGXvlaevSmZTi/zDxjTdXeTs8TQ9pQkNZKbCWaJXW29a3bGPRsASqeO+jGgZlaTUi9jTw==
|
||||
dependencies:
|
||||
"@types/jsbn" "*"
|
||||
|
||||
"@types/jsbn@*":
|
||||
version "1.2.29"
|
||||
resolved "https://registry.yarnpkg.com/@types/jsbn/-/jsbn-1.2.29.tgz#28229bc0262c704a1506c3ed69a7d7e115bd7832"
|
||||
integrity sha512-2dVz9LTEGWVj9Ov9zaDnpvqHFV+W4bXtU0EUEGAzWfdRNO3dlUuosdHpENI6/oQW+Kejn0hAjk6P/czs9h/hvg==
|
||||
|
||||
bunyan@0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-0.7.0.tgz#921065e70c936fe302a740e2c5605775beea2f42"
|
||||
integrity sha1-khBl5wyTb+MCp0DixWBXdb7qL0I=
|
||||
|
||||
"coffee-script@>= 1.1.1":
|
||||
version "1.12.7"
|
||||
resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.12.7.tgz#c05dae0cb79591d05b3070a8433a98c9a89ccc53"
|
||||
integrity sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==
|
||||
|
||||
ip-address@^5.8.9:
|
||||
version "5.8.9"
|
||||
resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-5.8.9.tgz#6379277c23fc5adb20511e4d23ec2c1bde105dfd"
|
||||
integrity sha512-7ay355oMN34iXhET1BmCJVsHjOTSItEEIIpOs38qUC23AIhOy+xIPnkrTuEFjeLMrTJ7m8KMXWgWfy/2Vn9sDw==
|
||||
dependencies:
|
||||
jsbn "1.1.0"
|
||||
lodash.find "^4.6.0"
|
||||
lodash.max "^4.0.1"
|
||||
lodash.merge "^4.6.0"
|
||||
lodash.padstart "^4.6.1"
|
||||
lodash.repeat "^4.1.0"
|
||||
sprintf-js "1.1.0"
|
||||
|
||||
ipaddr.js@0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-0.1.1.tgz#28c6a7c116a021c555544f906ab1ad540b1d635a"
|
||||
integrity sha1-KManwRagIcVVVE+QarGtVAsdY1o=
|
||||
dependencies:
|
||||
coffee-script ">= 1.1.1"
|
||||
|
||||
jsbn@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040"
|
||||
integrity sha1-sBMHyym2GKHtJux56RH4A8TaAEA=
|
||||
|
||||
lodash.find@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.find/-/lodash.find-4.6.0.tgz#cb0704d47ab71789ffa0de8b97dd926fb88b13b1"
|
||||
integrity sha1-ywcE1Hq3F4n/oN6Ll92Sb7iLE7E=
|
||||
|
||||
lodash.max@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.max/-/lodash.max-4.0.1.tgz#8735566c618b35a9f760520b487ae79658af136a"
|
||||
integrity sha1-hzVWbGGLNan3YFILSHrnllivE2o=
|
||||
|
||||
lodash.merge@^4.6.0:
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54"
|
||||
integrity sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==
|
||||
|
||||
lodash.padstart@^4.6.1:
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.padstart/-/lodash.padstart-4.6.1.tgz#d2e3eebff0d9d39ad50f5cbd1b52a7bce6bb611b"
|
||||
integrity sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs=
|
||||
|
||||
lodash.repeat@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.repeat/-/lodash.repeat-4.1.0.tgz#fc7de8131d8c8ac07e4b49f74ffe829d1f2bec44"
|
||||
integrity sha1-/H3oEx2MisB+S0n3T/6CnR8r7EQ=
|
||||
|
||||
node-named@^0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/node-named/-/node-named-0.0.1.tgz#3607b434cf237ab99440f5ff6d19c05e3a93e217"
|
||||
integrity sha1-Nge0NM8jermUQPX/bRnAXjqT4hc=
|
||||
dependencies:
|
||||
bunyan "0.7.0"
|
||||
ipaddr.js "0.1.1"
|
||||
|
||||
sprintf-js@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.0.tgz#cffcaf702daf65ea39bb4e0fa2b299cec1a1be46"
|
||||
integrity sha1-z/yvcC2vZeo5u04PorKZzsGhvkY=
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"name": "@coder/events",
|
||||
"main": "./src/index.ts"
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
import { IDisposable } from "@coder/disposable";
|
||||
|
||||
export interface Event<T> {
|
||||
(listener: (e: T) => void): IDisposable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emitter typecasts for a single event type.
|
||||
*/
|
||||
export class Emitter<T> {
|
||||
private listeners = <Array<(e: T) => void>>[];
|
||||
|
||||
public get event(): Event<T> {
|
||||
return (cb: (e: T) => void): IDisposable => {
|
||||
if (this.listeners) {
|
||||
this.listeners.push(cb);
|
||||
}
|
||||
|
||||
return {
|
||||
dispose: (): void => {
|
||||
if (this.listeners) {
|
||||
const i = this.listeners.indexOf(cb);
|
||||
if (i !== -1) {
|
||||
this.listeners.splice(i, 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit an event with a value.
|
||||
*/
|
||||
public emit(value: T): void {
|
||||
if (this.listeners) {
|
||||
this.listeners.forEach((t) => t(value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispose the current events.
|
||||
*/
|
||||
public dispose(): void {
|
||||
this.listeners = [];
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export * from "./events";
|
||||
@@ -1,4 +0,0 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# ide-api
|
||||
|
||||
Provides window listeners for interfacing with the IDE.
|
||||
|
||||
Created for content-scripts.
|
||||
222
packages/ide-api/api.d.ts
vendored
@@ -1,222 +0,0 @@
|
||||
export interface EvalHelper { }
|
||||
interface ActiveEvalEmitter {
|
||||
removeAllListeners(event?: string): void;
|
||||
emit(event: string, ...args: any[]): void;
|
||||
on(event: string, cb: (...args: any[]) => void): void;
|
||||
}
|
||||
interface IDisposable {
|
||||
dispose(): void;
|
||||
}
|
||||
interface Disposer extends IDisposable {
|
||||
onDidDispose: (cb: () => void) => void;
|
||||
}
|
||||
interface Event<T> {
|
||||
(listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[]): IDisposable;
|
||||
}
|
||||
interface IAction extends IDisposable {
|
||||
id: string;
|
||||
label: string;
|
||||
tooltip: string;
|
||||
class: string | undefined;
|
||||
enabled: boolean;
|
||||
checked: boolean;
|
||||
radio: boolean;
|
||||
run(event?: any): Promise<any>;
|
||||
}
|
||||
interface IStatusbarEntry {
|
||||
readonly text: string;
|
||||
readonly tooltip?: string;
|
||||
readonly color?: string;
|
||||
readonly command?: string;
|
||||
readonly arguments?: any[];
|
||||
readonly showBeak?: boolean;
|
||||
}
|
||||
interface IStatusbarService {
|
||||
addEntry(entry: IStatusbarEntry, alignment: ide.StatusbarAlignment, priority?: number): IDisposable;
|
||||
setStatusMessage(message: string, autoDisposeAfter?: number, delayBy?: number): IDisposable;
|
||||
}
|
||||
type NotificationMessage = string | Error;
|
||||
interface INotificationProperties {
|
||||
sticky?: boolean;
|
||||
silent?: boolean;
|
||||
}
|
||||
interface INotification extends INotificationProperties {
|
||||
severity: ide.Severity;
|
||||
message: NotificationMessage;
|
||||
source?: string;
|
||||
actions?: INotificationActions;
|
||||
}
|
||||
interface INotificationActions {
|
||||
primary?: IAction[];
|
||||
secondary?: IAction[];
|
||||
}
|
||||
|
||||
interface INotificationProgress {
|
||||
infinite(): void;
|
||||
total(value: number): void;
|
||||
worked(value: number): void;
|
||||
done(): void;
|
||||
}
|
||||
|
||||
interface INotificationHandle {
|
||||
readonly onDidClose: Event<void>;
|
||||
readonly progress: INotificationProgress;
|
||||
updateSeverity(severity: ide.Severity): void;
|
||||
updateMessage(message: NotificationMessage): void;
|
||||
updateActions(actions?: INotificationActions): void;
|
||||
close(): void;
|
||||
}
|
||||
|
||||
interface IPromptChoice {
|
||||
label: string;
|
||||
isSecondary?: boolean;
|
||||
keepOpen?: boolean;
|
||||
run: () => void;
|
||||
}
|
||||
|
||||
interface IPromptOptions extends INotificationProperties {
|
||||
onCancel?: () => void;
|
||||
}
|
||||
|
||||
interface INotificationService {
|
||||
notify(notification: INotification): INotificationHandle;
|
||||
info(message: NotificationMessage | NotificationMessage[]): void;
|
||||
warn(message: NotificationMessage | NotificationMessage[]): void;
|
||||
error(message: NotificationMessage | NotificationMessage[]): void;
|
||||
prompt(severity: ide.Severity, message: string, choices: IPromptChoice[], options?: IPromptOptions): INotificationHandle;
|
||||
}
|
||||
|
||||
interface IBaseCommandAction {
|
||||
id: string;
|
||||
title: string;
|
||||
category?: string;
|
||||
}
|
||||
|
||||
interface ICommandAction extends IBaseCommandAction {
|
||||
// iconLocation?: { dark: URI; light?: URI; };
|
||||
// precondition?: ContextKeyExpr;
|
||||
// toggled?: ContextKeyExpr;
|
||||
}
|
||||
|
||||
interface ISerializableCommandAction extends IBaseCommandAction {
|
||||
// iconLocation?: { dark: UriComponents; light?: UriComponents; };
|
||||
}
|
||||
|
||||
interface IMenuItem {
|
||||
command: ICommandAction;
|
||||
alt?: ICommandAction;
|
||||
// when?: ContextKeyExpr;
|
||||
group?: 'navigation' | string;
|
||||
order?: number;
|
||||
}
|
||||
|
||||
interface IMenuRegistry {
|
||||
appendMenuItem(menu: ide.MenuId, item: IMenuItem): IDisposable;
|
||||
}
|
||||
|
||||
export interface ICommandHandler {
|
||||
(accessor: any, ...args: any[]): void;
|
||||
}
|
||||
|
||||
export interface ICommand {
|
||||
id: string;
|
||||
handler: ICommandHandler;
|
||||
description?: ICommandHandlerDescription | null;
|
||||
}
|
||||
|
||||
export interface ICommandHandlerDescription {
|
||||
description: string;
|
||||
args: { name: string; description?: string; }[];
|
||||
returns?: string;
|
||||
}
|
||||
|
||||
interface ICommandRegistry {
|
||||
registerCommand(command: ICommand): IDisposable;
|
||||
}
|
||||
|
||||
declare namespace ide {
|
||||
export const client: {
|
||||
run(func: (helper: ActiveEvalEmitter) => Disposer): ActiveEvalEmitter;
|
||||
run<T1>(func: (helper: ActiveEvalEmitter, a1: T1) => Disposer, a1: T1): ActiveEvalEmitter;
|
||||
run<T1, T2>(func: (helper: ActiveEvalEmitter, a1: T1, a2: T2) => Disposer, a1: T1, a2: T2): ActiveEvalEmitter;
|
||||
run<T1, T2, T3>(func: (helper: ActiveEvalEmitter, a1: T1, a2: T2, a3: T3) => Disposer, a1: T1, a2: T2, a3: T3): ActiveEvalEmitter;
|
||||
run<T1, T2, T3, T4>(func: (helper: ActiveEvalEmitter, a1: T1, a2: T2, a3: T3, a4: T4) => Disposer, a1: T1, a2: T2, a3: T3, a4: T4): ActiveEvalEmitter;
|
||||
run<T1, T2, T3, T4, T5>(func: (helper: ActiveEvalEmitter, a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) => Disposer, a1: T1, a2: T2, a3: T3, a4: T4, a5: T5): ActiveEvalEmitter;
|
||||
run<T1, T2, T3, T4, T5, T6>(func: (helper: ActiveEvalEmitter, a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6) => Disposer, a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6): ActiveEvalEmitter;
|
||||
|
||||
evaluate<R>(func: (helper: EvalHelper) => R | Promise<R>): Promise<R>;
|
||||
evaluate<R, T1>(func: (helper: EvalHelper, a1: T1) => R | Promise<R>, a1: T1): Promise<R>;
|
||||
evaluate<R, T1, T2>(func: (helper: EvalHelper, a1: T1, a2: T2) => R | Promise<R>, a1: T1, a2: T2): Promise<R>;
|
||||
evaluate<R, T1, T2, T3>(func: (helper: EvalHelper, a1: T1, a2: T2, a3: T3) => R | Promise<R>, a1: T1, a2: T2, a3: T3): Promise<R>;
|
||||
evaluate<R, T1, T2, T3, T4>(func: (helper: EvalHelper, a1: T1, a2: T2, a3: T3, a4: T4) => R | Promise<R>, a1: T1, a2: T2, a3: T3, a4: T4): Promise<R>;
|
||||
evaluate<R, T1, T2, T3, T4, T5>(func: (helper: EvalHelper, a1: T1, a2: T2, a3: T3, a4: T4, a5: T5) => R | Promise<R>, a1: T1, a2: T2, a3: T3, a4: T4, a5: T5): Promise<R>;
|
||||
evaluate<R, T1, T2, T3, T4, T5, T6>(func: (helper: EvalHelper, a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6) => R | Promise<R>, a1: T1, a2: T2, a3: T3, a4: T4, a5: T5, a6: T6): Promise<R>;
|
||||
};
|
||||
|
||||
export const workbench: {
|
||||
readonly statusbarService: IStatusbarService;
|
||||
readonly notificationService: INotificationService;
|
||||
readonly menuRegistry: IMenuRegistry;
|
||||
readonly commandRegistry: ICommandRegistry;
|
||||
};
|
||||
|
||||
export enum Severity {
|
||||
Ignore = 0,
|
||||
Info = 1,
|
||||
Warning = 2,
|
||||
Error = 3
|
||||
}
|
||||
|
||||
export enum StatusbarAlignment {
|
||||
LEFT = 0,
|
||||
RIGHT = 1,
|
||||
}
|
||||
|
||||
export enum MenuId {
|
||||
CommandPalette,
|
||||
DebugBreakpointsContext,
|
||||
DebugCallStackContext,
|
||||
DebugConsoleContext,
|
||||
DebugVariablesContext,
|
||||
DebugWatchContext,
|
||||
EditorContext,
|
||||
EditorTitle,
|
||||
EditorTitleContext,
|
||||
EmptyEditorGroupContext,
|
||||
ExplorerContext,
|
||||
MenubarAppearanceMenu,
|
||||
MenubarDebugMenu,
|
||||
MenubarEditMenu,
|
||||
MenubarFileMenu,
|
||||
MenubarGoMenu,
|
||||
MenubarHelpMenu,
|
||||
MenubarLayoutMenu,
|
||||
MenubarNewBreakpointMenu,
|
||||
MenubarPreferencesMenu,
|
||||
MenubarRecentMenu,
|
||||
MenubarSelectionMenu,
|
||||
MenubarSwitchEditorMenu,
|
||||
MenubarSwitchGroupMenu,
|
||||
MenubarTerminalMenu,
|
||||
MenubarViewMenu,
|
||||
OpenEditorsContext,
|
||||
ProblemsPanelContext,
|
||||
SCMChangeContext,
|
||||
SCMResourceContext,
|
||||
SCMResourceGroupContext,
|
||||
SCMSourceControl,
|
||||
SCMTitle,
|
||||
SearchContext,
|
||||
TouchBarContext,
|
||||
ViewItemContext,
|
||||
ViewTitle,
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
ide?: typeof ide;
|
||||
|
||||
addEventListener(event: "ide-ready", callback: (ide: CustomEvent & { readonly ide: typeof ide }) => void): void;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"name": "@coder/ide-api",
|
||||
"version": "1.0.2",
|
||||
"typings": "api.d.ts",
|
||||
"author": "Coder",
|
||||
"license": "MIT",
|
||||
"description": "API for interfacing with the API created for content-scripts"
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "@coder/ide",
|
||||
"description": "Browser-based IDE client abstraction.",
|
||||
"main": "src/index.ts",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@types/rimraf": "^2.0.2",
|
||||
"rimraf": "^2.6.3"
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
import { field, logger, time, Time } from "@coder/logger";
|
||||
import { SharedProcessData } from "@coder/protocol";
|
||||
import { retry } from "./retry";
|
||||
import { upload } from "./upload";
|
||||
import { client } from "./fill/client";
|
||||
import { clipboard } from "./fill/clipboard";
|
||||
import { INotificationService, IProgressService } from "./fill/notification";
|
||||
import "./fill/os"; // Ensure it fills before anything else waiting on initData.
|
||||
|
||||
/**
|
||||
* A general abstraction of an IDE client.
|
||||
*
|
||||
* Everything the client provides is asynchronous so you can wait on what
|
||||
* you need from it without blocking anything else.
|
||||
*
|
||||
* It also provides task management to help asynchronously load and time code.
|
||||
*/
|
||||
export abstract class IdeClient {
|
||||
public readonly retry = retry;
|
||||
public readonly clipboard = clipboard;
|
||||
public readonly upload = upload;
|
||||
|
||||
private start: Time | undefined;
|
||||
private readonly tasks = <string[]>[];
|
||||
private finishedTaskCount = 0;
|
||||
private readonly loadTime: Time;
|
||||
|
||||
public readonly initData = client.initData;
|
||||
public readonly sharedProcessData: Promise<SharedProcessData>;
|
||||
public readonly onSharedProcessActive = client.onSharedProcessActive;
|
||||
|
||||
public constructor() {
|
||||
logger.info("Loading IDE");
|
||||
this.loadTime = time(2500);
|
||||
|
||||
let appWindow: Window | undefined;
|
||||
window.addEventListener("message", (event) => {
|
||||
if (event.data === "app") {
|
||||
appWindow = event.source as Window;
|
||||
}
|
||||
});
|
||||
|
||||
this.sharedProcessData = new Promise((resolve): void => {
|
||||
client.onSharedProcessActive(resolve);
|
||||
});
|
||||
|
||||
window.addEventListener("contextmenu", (event) => {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
// Prevent Firefox from trying to reconnect when the page unloads.
|
||||
window.addEventListener("unload", () => {
|
||||
this.retry.block();
|
||||
logger.info("Unloaded");
|
||||
});
|
||||
|
||||
this.initialize().then(() => {
|
||||
logger.info("Load completed", field("duration", this.loadTime));
|
||||
if (appWindow) {
|
||||
appWindow.postMessage("loaded", "*");
|
||||
}
|
||||
}).catch((error) => {
|
||||
logger.error(error.message);
|
||||
logger.warn("Load completed with errors", field("duration", this.loadTime));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a task in some logging, timing, and progress updates. Can optionally
|
||||
* wait on other tasks which won't count towards this task's time.
|
||||
*/
|
||||
public async task<T>(description: string, duration: number, task: () => Promise<T>): Promise<T>;
|
||||
public async task<T, V>(description: string, duration: number, task: (v: V) => Promise<T>, t: Promise<V>): Promise<T>;
|
||||
public async task<T, V1, V2>(description: string, duration: number, task: (v1: V1, v2: V2) => Promise<T>, t1: Promise<V1>, t2: Promise<V2>): Promise<T>;
|
||||
public async task<T, V1, V2, V3>(description: string, duration: number, task: (v1: V1, v2: V2, v3: V3) => Promise<T>, t1: Promise<V1>, t2: Promise<V2>, t3: Promise<V3>): Promise<T>;
|
||||
public async task<T, V1, V2, V3, V4>(description: string, duration: number, task: (v1: V1, v2: V2, v3: V3, v4: V4) => Promise<T>, t1: Promise<V1>, t2: Promise<V2>, t3: Promise<V3>, t4: Promise<V4>): Promise<T>;
|
||||
public async task<T, V1, V2, V3, V4, V5>(description: string, duration: number, task: (v1: V1, v2: V2, v3: V3, v4: V4, v5: V5) => Promise<T>, t1: Promise<V1>, t2: Promise<V2>, t3: Promise<V3>, t4: Promise<V4>, t5: Promise<V5>): Promise<T>;
|
||||
public async task<T, V1, V2, V3, V4, V5, V6>(description: string, duration: number, task: (v1: V1, v2: V2, v3: V3, v4: V4, v5: V5, v6: V6) => Promise<T>, t1: Promise<V1>, t2: Promise<V2>, t3: Promise<V3>, t4: Promise<V4>, t5: Promise<V5>, t6: Promise<V6>): Promise<T>;
|
||||
public async task<T>(
|
||||
description: string, duration: number = 100, task: (...args: any[]) => Promise<T>, ...after: Array<Promise<any>> // tslint:disable-line no-any
|
||||
): Promise<T> {
|
||||
this.tasks.push(description);
|
||||
if (!this.start) {
|
||||
this.start = time(1000);
|
||||
}
|
||||
|
||||
let start: Time | undefined;
|
||||
try {
|
||||
const waitFor = await (after && after.length > 0 ? Promise.all(after) : Promise.resolve([]));
|
||||
start = time(duration);
|
||||
logger.info(description);
|
||||
const value = await task(...waitFor);
|
||||
logger.info(`Finished "${description}"`, field("duration", start));
|
||||
const index = this.tasks.indexOf(description);
|
||||
if (index !== -1) {
|
||||
this.tasks.splice(index, 1);
|
||||
}
|
||||
++this.finishedTaskCount;
|
||||
if (this.tasks.length === 0) {
|
||||
logger.info("Finished all queued tasks", field("duration", this.start), field("count", this.finishedTaskCount));
|
||||
this.start = undefined;
|
||||
}
|
||||
|
||||
return value;
|
||||
} catch (error) {
|
||||
logger.error(`Failed "${description}"`, field("duration", typeof start !== "undefined" ? start : "not started"), field("error", error));
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
public set notificationService(service: INotificationService) {
|
||||
this.retry.notificationService = service;
|
||||
this.upload.notificationService = service;
|
||||
}
|
||||
|
||||
public set progressService(service: IProgressService) {
|
||||
this.upload.progressService = service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the IDE.
|
||||
*/
|
||||
protected abstract initialize(): Promise<void>;
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
import * as cp from "child_process";
|
||||
import * as net from "net";
|
||||
import * as stream from "stream";
|
||||
import { CallbackEmitter, ActiveEvalReadable, ActiveEvalWritable } from "@coder/protocol";
|
||||
import { client } from "./client";
|
||||
import { promisify } from "util";
|
||||
|
||||
declare var __non_webpack_require__: typeof require;
|
||||
|
||||
class ChildProcess extends CallbackEmitter implements cp.ChildProcess {
|
||||
private _connected: boolean = false;
|
||||
private _killed: boolean = false;
|
||||
private _pid = -1;
|
||||
public readonly stdin: stream.Writable;
|
||||
public readonly stdout: stream.Readable;
|
||||
public readonly stderr: stream.Readable;
|
||||
// We need the explicit type otherwise TypeScript thinks it is (Writable | Readable)[].
|
||||
public readonly stdio: [stream.Writable, stream.Readable, stream.Readable] = [this.stdin, this.stdout, this.stderr];
|
||||
|
||||
// tslint:disable no-any
|
||||
public constructor(method: "exec", command: string, options?: { encoding?: string | null } & cp.ExecOptions | null, callback?: (...args: any[]) => void);
|
||||
public constructor(method: "fork", modulePath: string, options?: cp.ForkOptions, args?: string[]);
|
||||
public constructor(method: "spawn", command: string, options?: cp.SpawnOptions, args?: string[]);
|
||||
public constructor(method: "exec" | "spawn" | "fork", command: string, options: object = {}, callback?: string[] | ((...args: any[]) => void)) {
|
||||
// tslint:enable no-any
|
||||
super();
|
||||
|
||||
let args: string[] = [];
|
||||
if (Array.isArray(callback)) {
|
||||
args = callback;
|
||||
callback = undefined;
|
||||
}
|
||||
|
||||
this.ae = client.run((ae, command, method, args, options, callbackId) => {
|
||||
const cp = __non_webpack_require__("child_process") as typeof import("child_process");
|
||||
|
||||
ae.preserveEnv(options);
|
||||
|
||||
let childProcess: cp.ChildProcess;
|
||||
switch (method) {
|
||||
case "exec":
|
||||
childProcess = cp.exec(command, options, ae.maybeCallback(callbackId));
|
||||
break;
|
||||
case "spawn":
|
||||
childProcess = cp.spawn(command, args, options);
|
||||
break;
|
||||
case "fork":
|
||||
childProcess = ae.fork(command, args, options);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`invalid method ${method}`);
|
||||
}
|
||||
|
||||
ae.on("disconnect", () => childProcess.disconnect());
|
||||
ae.on("kill", (signal: string) => childProcess.kill(signal));
|
||||
ae.on("ref", () => childProcess.ref());
|
||||
ae.on("send", (message: string, callbackId: number) => childProcess.send(message, ae.maybeCallback(callbackId)));
|
||||
ae.on("unref", () => childProcess.unref());
|
||||
|
||||
ae.emit("pid", childProcess.pid);
|
||||
childProcess.on("close", (code, signal) => ae.emit("close", code, signal));
|
||||
childProcess.on("disconnect", () => ae.emit("disconnect"));
|
||||
childProcess.on("error", (error) => ae.emit("error", error));
|
||||
childProcess.on("exit", (code, signal) => ae.emit("exit", code, signal));
|
||||
childProcess.on("message", (message) => ae.emit("message", message));
|
||||
|
||||
if (childProcess.stdin) {
|
||||
const stdinAe = ae.createUnique("stdin");
|
||||
stdinAe.bindWritable(childProcess.stdin);
|
||||
}
|
||||
if (childProcess.stdout) {
|
||||
const stdoutAe = ae.createUnique("stdout");
|
||||
stdoutAe.bindReadable(childProcess.stdout);
|
||||
}
|
||||
if (childProcess.stderr) {
|
||||
const stderrAe = ae.createUnique("stderr");
|
||||
stderrAe.bindReadable(childProcess.stderr);
|
||||
}
|
||||
|
||||
return {
|
||||
onDidDispose: (cb): cp.ChildProcess => childProcess.on("close", cb),
|
||||
dispose: (): void => {
|
||||
childProcess.kill();
|
||||
setTimeout(() => childProcess.kill("SIGKILL"), 5000); // Double tap.
|
||||
},
|
||||
};
|
||||
}, command, method, args, options, this.storeCallback(callback));
|
||||
|
||||
this.ae.on("pid", (pid) => {
|
||||
this._pid = pid;
|
||||
this._connected = true;
|
||||
});
|
||||
|
||||
this.stdin = new ActiveEvalWritable(this.ae.createUnique("stdin"));
|
||||
this.stdout = new ActiveEvalReadable(this.ae.createUnique("stdout"));
|
||||
this.stderr = new ActiveEvalReadable(this.ae.createUnique("stderr"));
|
||||
|
||||
this.ae.on("close", (code, signal) => this.emit("close", code, signal));
|
||||
this.ae.on("disconnect", () => this.emit("disconnect"));
|
||||
this.ae.on("error", (error) => this.emit("error", error));
|
||||
this.ae.on("exit", (code, signal) => {
|
||||
this._connected = false;
|
||||
this._killed = true;
|
||||
this.emit("exit", code, signal);
|
||||
});
|
||||
this.ae.on("message", (message) => this.emit("message", message));
|
||||
}
|
||||
|
||||
public get pid(): number { return this._pid; }
|
||||
public get connected(): boolean { return this._connected; }
|
||||
public get killed(): boolean { return this._killed; }
|
||||
|
||||
public kill(): void { this.ae.emit("kill"); }
|
||||
public disconnect(): void { this.ae.emit("disconnect"); }
|
||||
public ref(): void { this.ae.emit("ref"); }
|
||||
public unref(): void { this.ae.emit("unref"); }
|
||||
|
||||
public send(
|
||||
message: any, // tslint:disable-line no-any to match spec
|
||||
sendHandle?: net.Socket | net.Server | ((error: Error) => void),
|
||||
options?: cp.MessageOptions | ((error: Error) => void),
|
||||
callback?: (error: Error) => void): boolean {
|
||||
if (typeof sendHandle === "function") {
|
||||
callback = sendHandle;
|
||||
sendHandle = undefined;
|
||||
} else if (typeof options === "function") {
|
||||
callback = options;
|
||||
options = undefined;
|
||||
}
|
||||
if (sendHandle || options) {
|
||||
throw new Error("sendHandle and options are not supported");
|
||||
}
|
||||
this.ae.emit("send", message, this.storeCallback(callback));
|
||||
|
||||
// Unfortunately this will always have to be true since we can't retrieve
|
||||
// the actual response synchronously.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class CP {
|
||||
public readonly ChildProcess = ChildProcess;
|
||||
|
||||
public exec = (
|
||||
command: string,
|
||||
options?: { encoding?: string | null } & cp.ExecOptions | null | ((error: cp.ExecException | null, stdout: string, stderr: string) => void) | ((error: cp.ExecException | null, stdout: Buffer, stderr: Buffer) => void),
|
||||
callback?: ((error: cp.ExecException | null, stdout: string, stderr: string) => void) | ((error: cp.ExecException | null, stdout: Buffer, stderr: Buffer) => void),
|
||||
): cp.ChildProcess => {
|
||||
if (typeof options === "function") {
|
||||
callback = options;
|
||||
options = undefined;
|
||||
}
|
||||
|
||||
return new ChildProcess("exec", command, options, callback);
|
||||
}
|
||||
|
||||
public fork = (modulePath: string, args?: string[] | cp.ForkOptions, options?: cp.ForkOptions): cp.ChildProcess => {
|
||||
if (args && !Array.isArray(args)) {
|
||||
options = args;
|
||||
args = undefined;
|
||||
}
|
||||
|
||||
return new ChildProcess("fork", modulePath, options, args);
|
||||
}
|
||||
|
||||
public spawn = (command: string, args?: string[] | cp.SpawnOptions, options?: cp.SpawnOptions): cp.ChildProcess => {
|
||||
if (args && !Array.isArray(args)) {
|
||||
options = args;
|
||||
args = undefined;
|
||||
}
|
||||
|
||||
return new ChildProcess("spawn", command, options, args);
|
||||
}
|
||||
}
|
||||
|
||||
const fillCp = new CP();
|
||||
// Methods that don't follow the standard callback pattern (an error followed
|
||||
// by a single result) need to provide a custom promisify function.
|
||||
Object.defineProperty(fillCp.exec, promisify.custom, {
|
||||
value: (
|
||||
command: string,
|
||||
options?: { encoding?: string | null } & cp.ExecOptions | null,
|
||||
): Promise<{ stdout: string | Buffer, stderr: string | Buffer }> => {
|
||||
return new Promise((resolve, reject): void => {
|
||||
fillCp.exec(command, options, (error: cp.ExecException | null, stdout: string | Buffer, stderr: string | Buffer) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve({ stdout, stderr });
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
export = fillCp;
|
||||
@@ -1,132 +0,0 @@
|
||||
import { Emitter } from "@coder/events";
|
||||
import { field, logger } from "@coder/logger";
|
||||
import { Client, ReadWriteConnection } from "@coder/protocol";
|
||||
import { retry } from "../retry";
|
||||
|
||||
/**
|
||||
* A connection based on a web socket. Automatically reconnects and buffers
|
||||
* messages during connection.
|
||||
*/
|
||||
class WebsocketConnection implements ReadWriteConnection {
|
||||
private activeSocket: WebSocket | undefined;
|
||||
private readonly messageBuffer = <Uint8Array[]>[];
|
||||
private readonly socketTimeoutDelay = 60 * 1000;
|
||||
private readonly retryName = "Socket";
|
||||
private isUp: boolean = false;
|
||||
private closed: boolean = false;
|
||||
|
||||
private readonly messageEmitter = new Emitter<Uint8Array>();
|
||||
private readonly closeEmitter = new Emitter<void>();
|
||||
private readonly upEmitter = new Emitter<void>();
|
||||
private readonly downEmitter = new Emitter<void>();
|
||||
|
||||
public readonly onUp = this.upEmitter.event;
|
||||
public readonly onClose = this.closeEmitter.event;
|
||||
public readonly onDown = this.downEmitter.event;
|
||||
public readonly onMessage = this.messageEmitter.event;
|
||||
|
||||
public constructor() {
|
||||
retry.register(this.retryName, () => this.connect());
|
||||
retry.block(this.retryName);
|
||||
retry.run(this.retryName);
|
||||
}
|
||||
|
||||
public send(data: Buffer | Uint8Array): void {
|
||||
if (this.closed) {
|
||||
throw new Error("web socket is closed");
|
||||
}
|
||||
if (!this.activeSocket || this.activeSocket.readyState !== this.activeSocket.OPEN) {
|
||||
this.messageBuffer.push(data);
|
||||
} else {
|
||||
this.activeSocket.send(data);
|
||||
}
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
this.closed = true;
|
||||
this.dispose();
|
||||
this.closeEmitter.emit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the server.
|
||||
*/
|
||||
private async connect(): Promise<void> {
|
||||
const socket = await this.openSocket();
|
||||
|
||||
socket.addEventListener("message", (event: MessageEvent) => {
|
||||
this.messageEmitter.emit(event.data);
|
||||
});
|
||||
|
||||
socket.addEventListener("close", (event) => {
|
||||
if (this.isUp) {
|
||||
this.isUp = false;
|
||||
this.downEmitter.emit(undefined);
|
||||
}
|
||||
logger.warn(
|
||||
"Web socket closed",
|
||||
field("code", event.code),
|
||||
field("reason", event.reason),
|
||||
field("wasClean", event.wasClean),
|
||||
);
|
||||
if (!this.closed) {
|
||||
retry.block(this.retryName);
|
||||
retry.run(this.retryName);
|
||||
}
|
||||
});
|
||||
|
||||
// Send any messages that were queued while we were waiting to connect.
|
||||
while (this.messageBuffer.length > 0) {
|
||||
socket.send(this.messageBuffer.shift()!);
|
||||
}
|
||||
|
||||
if (!this.isUp) {
|
||||
this.isUp = true;
|
||||
this.upEmitter.emit(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a web socket, disposing the previous connection if any.
|
||||
*/
|
||||
private async openSocket(): Promise<WebSocket> {
|
||||
this.dispose();
|
||||
const socket = new WebSocket(
|
||||
`${location.protocol === "https:" ? "wss" : "ws"}://${location.host}`,
|
||||
);
|
||||
socket.binaryType = "arraybuffer";
|
||||
this.activeSocket = socket;
|
||||
|
||||
const socketWaitTimeout = window.setTimeout(() => {
|
||||
socket.close();
|
||||
}, this.socketTimeoutDelay);
|
||||
|
||||
await new Promise((resolve, reject): void => {
|
||||
const onClose = (): void => {
|
||||
clearTimeout(socketWaitTimeout);
|
||||
socket.removeEventListener("close", onClose);
|
||||
reject();
|
||||
};
|
||||
socket.addEventListener("close", onClose);
|
||||
|
||||
socket.addEventListener("open", async () => {
|
||||
clearTimeout(socketWaitTimeout);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
return socket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispose the current connection.
|
||||
*/
|
||||
private dispose(): void {
|
||||
if (this.activeSocket) {
|
||||
this.activeSocket.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Global instance so all fills can use the same client.
|
||||
export const client = new Client(new WebsocketConnection());
|
||||
@@ -1,146 +0,0 @@
|
||||
import { Emitter } from "@coder/events";
|
||||
|
||||
/**
|
||||
* Wrapper around the native clipboard with some fallbacks.
|
||||
*/
|
||||
export class Clipboard {
|
||||
private readonly enableEmitter = new Emitter<boolean>();
|
||||
public readonly onPermissionChange = this.enableEmitter.event;
|
||||
private _isEnabled: boolean = false;
|
||||
|
||||
/**
|
||||
* Ask for permission to use the clipboard.
|
||||
*/
|
||||
public initialize(): void {
|
||||
// tslint:disable no-any
|
||||
const navigatorClip = (navigator as any).clipboard;
|
||||
const navigatorPerms = (navigator as any).permissions;
|
||||
// tslint:enable no-any
|
||||
if (navigatorClip && navigatorPerms) {
|
||||
navigatorPerms.query({
|
||||
name: "clipboard-read",
|
||||
}).then((permissionStatus: {
|
||||
onchange: () => void,
|
||||
state: "denied" | "granted" | "prompt",
|
||||
}) => {
|
||||
const updateStatus = (): void => {
|
||||
this._isEnabled = permissionStatus.state !== "denied";
|
||||
this.enableEmitter.emit(this.isEnabled);
|
||||
};
|
||||
updateStatus();
|
||||
permissionStatus.onchange = (): void => {
|
||||
updateStatus();
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Paste currently copied text.
|
||||
*/
|
||||
public async paste(): Promise<boolean> {
|
||||
if (this.isEnabled) {
|
||||
try {
|
||||
const element = document.activeElement as HTMLInputElement | HTMLTextAreaElement;
|
||||
const start = element.selectionStart || 0;
|
||||
const end = element.selectionEnd;
|
||||
const allText = element.value;
|
||||
const newText = allText.substring(0, start)
|
||||
+ (await this.readText())
|
||||
+ allText.substring(end || start);
|
||||
element.value = newText;
|
||||
|
||||
return true;
|
||||
} catch (ex) {
|
||||
// Will try execCommand below.
|
||||
}
|
||||
}
|
||||
|
||||
return document.execCommand("paste");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the native clipboard is supported.
|
||||
*/
|
||||
public get isSupported(): boolean {
|
||||
// tslint:disable no-any
|
||||
return typeof navigator !== "undefined"
|
||||
&& typeof (navigator as any).clipboard !== "undefined"
|
||||
&& typeof (navigator as any).clipboard.readText !== "undefined";
|
||||
// tslint:enable no-any
|
||||
}
|
||||
|
||||
/**
|
||||
* Read text from the clipboard.
|
||||
*/
|
||||
public readText(): Promise<string> {
|
||||
return this.instance ? this.instance.readText() : Promise.resolve("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write text to the clipboard.
|
||||
*/
|
||||
public writeText(value: string): Promise<void> {
|
||||
return this.instance
|
||||
? this.instance.writeText(value)
|
||||
: this.writeTextFallback(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the clipboard is currently enabled.
|
||||
*/
|
||||
public get isEnabled(): boolean {
|
||||
return !!this._isEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return clipboard instance if there is one.
|
||||
*/
|
||||
private get instance(): ({
|
||||
readText(): Promise<string>;
|
||||
writeText(value: string): Promise<void>;
|
||||
}) | undefined {
|
||||
// tslint:disable-next-line no-any
|
||||
return this.isSupported ? (navigator as any).clipboard : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback for writing text to the clipboard.
|
||||
* Taken from https://hackernoon.com/copying-text-to-clipboard-with-javascript-df4d4988697f
|
||||
*/
|
||||
private writeTextFallback(value: string): Promise<void> {
|
||||
// Note the current focus and selection.
|
||||
const active = document.activeElement as HTMLElement;
|
||||
const selection = document.getSelection();
|
||||
const selected = selection && selection.rangeCount > 0
|
||||
? selection.getRangeAt(0)
|
||||
: false;
|
||||
|
||||
// Insert a hidden textarea to put the text to copy in.
|
||||
const el = document.createElement("textarea");
|
||||
el.value = value;
|
||||
el.setAttribute("readonly", "");
|
||||
el.style.position = "absolute";
|
||||
el.style.left = "-9999px";
|
||||
document.body.appendChild(el);
|
||||
|
||||
// Select the textarea and execute a copy (this will only work as part of a
|
||||
// user interaction).
|
||||
el.select();
|
||||
document.execCommand("copy");
|
||||
|
||||
// Remove the textarea and put focus and selection back to where it was
|
||||
// previously.
|
||||
document.body.removeChild(el);
|
||||
active.focus();
|
||||
if (selected && selection) {
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(selected);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
// Global clipboard instance since it's used in the Electron fill.
|
||||
export const clipboard = new Clipboard();
|
||||