@jsenv/server 17.1.0 → 17.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/route_inspector/route_inspector.html +118 -35
- package/dist/jsenv_server.js +453 -17
- package/package.json +13 -13
- package/src/interfacing_with_node/from_node_request.js +19 -0
- package/src/internal/headers_composition.js +12 -0
- package/src/plugins/cookies/cookie.js +77 -0
- package/src/plugins/cookies/server_plugin_response_cookies.js +30 -0
- package/src/plugins/cors/server_plugin_cors.js +26 -13
- package/src/plugins/route_inspector/client/code_block.js +3 -1
- package/src/plugins/route_inspector/client/route_inspector.html +111 -34
- package/src/plugins/route_inspector/server_plugin_route_inspector.js +3 -2
- package/src/plugins/server_plugins_controller.js +1 -0
- package/src/plugins_controller.js +36 -0
- package/src/router/router.js +144 -2
- package/src/start_server.js +106 -0
- package/src/cookies/cookie.js +0 -42
- package/src/cookies/cookie_map.js +0 -18
|
@@ -121,7 +121,9 @@
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
customElements.
|
|
124
|
+
if (!customElements.get("clipboard-copy")) {
|
|
125
|
+
customElements.define("clipboard-copy", ClipboardCopy);
|
|
126
|
+
}
|
|
125
127
|
|
|
126
128
|
const addToClipboard = async (text) => {
|
|
127
129
|
const type = "text/plain";
|
|
@@ -404,6 +406,13 @@
|
|
|
404
406
|
--border-color: #e0e0e0;
|
|
405
407
|
--primary-color: #1976d2;
|
|
406
408
|
--secondary-color: #f5f5f5;
|
|
409
|
+
--forbidden-bg-color: #fff8f0;
|
|
410
|
+
--forbidden-border-color: #c80;
|
|
411
|
+
--forbidden-badge-bg: #fff3cc;
|
|
412
|
+
--forbidden-badge-color: #7a5000;
|
|
413
|
+
--admin-badge-bg: #f0f4ff;
|
|
414
|
+
--admin-badge-border-color: #5c7cfa;
|
|
415
|
+
--admin-badge-color: #2a4bbf;
|
|
407
416
|
}
|
|
408
417
|
|
|
409
418
|
:root[data-theme="dark"] {
|
|
@@ -412,6 +421,13 @@
|
|
|
412
421
|
--border-color: #333;
|
|
413
422
|
--primary-color: #4f9eff;
|
|
414
423
|
--secondary-color: #1e1e1e;
|
|
424
|
+
--forbidden-bg-color: #1e1500;
|
|
425
|
+
--forbidden-border-color: #8a6000;
|
|
426
|
+
--forbidden-badge-bg: #3a2800;
|
|
427
|
+
--forbidden-badge-color: #f0c060;
|
|
428
|
+
--admin-badge-bg: #0d1a3a;
|
|
429
|
+
--admin-badge-border-color: #3b5bdb;
|
|
430
|
+
--admin-badge-color: #91a7ff;
|
|
415
431
|
}
|
|
416
432
|
|
|
417
433
|
:root[data-theme="dark"] a {
|
|
@@ -841,6 +857,46 @@ main {
|
|
|
841
857
|
--method-color: var(--method-delete-color);
|
|
842
858
|
}
|
|
843
859
|
|
|
860
|
+
.route_details[data-forbidden] {
|
|
861
|
+
background: var(--forbidden-bg-color);
|
|
862
|
+
border-color: var(--forbidden-border-color);
|
|
863
|
+
opacity: .85;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
.route_details[data-forbidden] .route_method {
|
|
867
|
+
opacity: .7;
|
|
868
|
+
filter: grayscale(60%);
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
.route_forbidden_badge {
|
|
872
|
+
color: var(--forbidden-badge-color);
|
|
873
|
+
white-space: nowrap;
|
|
874
|
+
background: var(--forbidden-badge-bg);
|
|
875
|
+
border: 1px solid var(--forbidden-border-color);
|
|
876
|
+
border-radius: 4px;
|
|
877
|
+
margin-right: 6px;
|
|
878
|
+
padding: 3px 8px;
|
|
879
|
+
font-size: 12px;
|
|
880
|
+
font-weight: 600;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
.route_admin_badge {
|
|
884
|
+
color: var(--admin-badge-color);
|
|
885
|
+
white-space: nowrap;
|
|
886
|
+
background: var(--admin-badge-bg);
|
|
887
|
+
border: 1px solid var(--admin-badge-border-color);
|
|
888
|
+
border-radius: 4px;
|
|
889
|
+
margin-right: 6px;
|
|
890
|
+
padding: 3px 8px;
|
|
891
|
+
font-size: 12px;
|
|
892
|
+
font-weight: 600;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
.route_forbidden_content {
|
|
896
|
+
color: var(--forbidden-badge-color);
|
|
897
|
+
font-style: italic;
|
|
898
|
+
}
|
|
899
|
+
|
|
844
900
|
.route_owner_name {
|
|
845
901
|
color: #666;
|
|
846
902
|
text-align: center;
|
|
@@ -1755,6 +1811,8 @@ const routesLoadingSignal = P(false);
|
|
|
1755
1811
|
websocket,
|
|
1756
1812
|
clientCodeExample,
|
|
1757
1813
|
declarationSource,
|
|
1814
|
+
forbidden,
|
|
1815
|
+
visibleBecauseAdmin,
|
|
1758
1816
|
}) => {
|
|
1759
1817
|
const [selectedMethod] = useUrlStringParam("method");
|
|
1760
1818
|
const [selectedPackageName] = usePackageUrlStringParam();
|
|
@@ -1767,11 +1825,16 @@ const routesLoadingSignal = P(false);
|
|
|
1767
1825
|
return null;
|
|
1768
1826
|
}
|
|
1769
1827
|
|
|
1770
|
-
return p$3`<details
|
|
1828
|
+
return p$3`<details
|
|
1829
|
+
class="route_details"
|
|
1830
|
+
data-method="${method}"
|
|
1831
|
+
data-forbidden="${forbidden || undefined}"
|
|
1832
|
+
data-admin-visible="${visibleBecauseAdmin || undefined}"
|
|
1833
|
+
>
|
|
1771
1834
|
<summary class="route_summary_container">
|
|
1772
1835
|
<span class="route_method">${method}</span>
|
|
1773
1836
|
<p class="route_resource">${resource}</p>
|
|
1774
|
-
${method === "GET"
|
|
1837
|
+
${method === "GET" && !forbidden
|
|
1775
1838
|
? p$3`<a
|
|
1776
1839
|
style="display:inline-flex; margin-left: 5px;"
|
|
1777
1840
|
href="${resource}"
|
|
@@ -1779,25 +1842,45 @@ const routesLoadingSignal = P(false);
|
|
|
1779
1842
|
/></a>`
|
|
1780
1843
|
: null}
|
|
1781
1844
|
<span style="flex:1"></span>
|
|
1845
|
+
${visibleBecauseAdmin
|
|
1846
|
+
? p$3`<span
|
|
1847
|
+
class="route_admin_badge"
|
|
1848
|
+
title="This route is only visible because the server was started with canExposeSensitiveData"
|
|
1849
|
+
>🔒 admin only</span
|
|
1850
|
+
>`
|
|
1851
|
+
: null}
|
|
1852
|
+
${forbidden && !visibleBecauseAdmin
|
|
1853
|
+
? p$3`<span class="route_forbidden_badge"
|
|
1854
|
+
>🔒 access denied</span
|
|
1855
|
+
>`
|
|
1856
|
+
: null}
|
|
1782
1857
|
<${RouteBadge} meta="${meta}" />
|
|
1783
1858
|
<span class="summary_marker">
|
|
1784
1859
|
<${ArrowDown} />
|
|
1785
1860
|
</span>
|
|
1786
1861
|
</summary>
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1862
|
+
${!forbidden
|
|
1863
|
+
? p$3`<${RouteDetailsContent}
|
|
1864
|
+
method="${method}"
|
|
1865
|
+
resource="${resource}"
|
|
1866
|
+
description="${description}"
|
|
1867
|
+
availableMediaTypes="${availableMediaTypes}"
|
|
1868
|
+
availableLanguages="${availableLanguages}"
|
|
1869
|
+
availableVersions="${availableVersions}"
|
|
1870
|
+
availableEncodings="${availableEncodings}"
|
|
1871
|
+
acceptedMediaTypes="${acceptedMediaTypes}"
|
|
1872
|
+
websocket="${websocket}"
|
|
1873
|
+
clientCodeExample="${clientCodeExample}"
|
|
1874
|
+
declarationSource="${declarationSource}"
|
|
1875
|
+
meta="${meta}"
|
|
1876
|
+
/>`
|
|
1877
|
+
: p$3`<div class="route_details_content route_forbidden_content">
|
|
1878
|
+
<p>
|
|
1879
|
+
${visibleBecauseAdmin
|
|
1880
|
+
? "This route is only visible because the server was started with canExposeSensitiveData. Access is denied with the current permissions."
|
|
1881
|
+
: "You do not have the required permissions to access this route."}
|
|
1882
|
+
</p>
|
|
1883
|
+
</div>`}
|
|
1801
1884
|
</details>`;
|
|
1802
1885
|
};
|
|
1803
1886
|
|
|
@@ -1928,26 +2011,26 @@ const routesLoadingSignal = P(false);
|
|
|
1928
2011
|
const websocketScheme =
|
|
1929
2012
|
self.location.protocol === "https:" ? "wss" : "ws";
|
|
1930
2013
|
const websocketOrigin = `${websocketScheme}://${self.location.host}`;
|
|
1931
|
-
jsSource =
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
2014
|
+
jsSource = `
|
|
2015
|
+
const websocket = new WebSocket("${websocketOrigin}${resource}");
|
|
2016
|
+
websocket.onerror = () => {
|
|
2017
|
+
console.error("Failed to connect to websocket endpoint");
|
|
2018
|
+
};
|
|
2019
|
+
websocket.onopen = () => {
|
|
2020
|
+
console.info("Connected to websocket endpoint");
|
|
2021
|
+
};
|
|
2022
|
+
websocket.onmessage = (event) => {
|
|
2023
|
+
console.log("Received message", event.data);
|
|
2024
|
+
};
|
|
2025
|
+
`;
|
|
1943
2026
|
} else {
|
|
1944
2027
|
let fetchLine;
|
|
1945
2028
|
if (method === "GET") {
|
|
1946
2029
|
fetchLine = `const response = await window.fetch("${resource}");`;
|
|
1947
2030
|
} else {
|
|
1948
2031
|
fetchLine = `const response = await window.fetch("${resource}", {
|
|
1949
|
-
|
|
1950
|
-
|
|
2032
|
+
method: "${method}",
|
|
2033
|
+
}`;
|
|
1951
2034
|
}
|
|
1952
2035
|
let readResponseLine;
|
|
1953
2036
|
if (availableMediaTypes.includes("application/json")) {
|
|
@@ -1956,10 +2039,10 @@ const routesLoadingSignal = P(false);
|
|
|
1956
2039
|
readResponseLine = `const text = await response.text();`;
|
|
1957
2040
|
}
|
|
1958
2041
|
|
|
1959
|
-
jsSource =
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
2042
|
+
jsSource = `
|
|
2043
|
+
${fetchLine};
|
|
2044
|
+
${readResponseLine};
|
|
2045
|
+
`;
|
|
1963
2046
|
}
|
|
1964
2047
|
|
|
1965
2048
|
return p$3`<code-block lang="js" data-escaped data-copy-button
|