diff --git a/README.md b/README.md index efe5b70b..3dd662f6 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,8 @@ making changes to the API. ### Running jsr -1. `deno task services:macos`, `deno task services:macos:amd` or `deno task services:linux` in one terminal +1. `deno task services:macos`, `deno task services:macos:amd` or + `deno task services:linux` in one terminal 2. `deno task dev:api` in another terminal 3. `deno task dev:frontend` in another terminal @@ -135,10 +136,12 @@ registry with data is to publish [deno_std](https://github.com/denoland/deno_std) to the registry. This can be done via the following steps: -1. Make sure to [make yourself a staff user/admin](#making-yourself-a-staff-useradmin). +1. Make sure to + [make yourself a staff user/admin](#making-yourself-a-staff-useradmin). 2. Navigate to your profile page and copy the UUID from the URL. -3. Assign the `std` scope to your user through the [admin panel](http://jsr.test/admin/scopes/assign) - by using the UUID from the previous step. +3. Assign the `std` scope to your user through the + [admin panel](http://jsr.test/admin/scopes/assign) by using the UUID from the + previous step. 4. Clone https://github.com/denoland/deno_std in the same parent folder as the `jsr` project. 5. Run `JSR_URL=http://jsr.test deno publish` to publish all of the @std diff --git a/deno.json b/deno.json index 0ebaa7b6..fc784d35 100644 --- a/deno.json +++ b/deno.json @@ -5,10 +5,11 @@ "services:linux": "docker compose up & ./tools/bin/linux-amd64/fake-gcs-server -scheme http -port 4080 -filesystem-root=.gcs & ./tools/server.ts", "services:linux-no-postgres": "docker compose up jaeger & ./tools/bin/linux-amd64/fake-gcs-server -scheme http -port 4080 -filesystem-root=.gcs & ./tools/server.ts", "dev:api": "cd api && cargo run", - "dev:frontend": "cd frontend && OLTP_ENDPOINT=http://localhost:4318 deno task start", - "prod:frontend": "deno run -A --watch ./tools/prod_proxy.ts & cd frontend && API_ROOT=https://api.jsr.io deno task start", - "lint": "deno task lint:frontend && deno task lint:license", - "lint:frontend": "cd frontend && deno lint && deno check --allow-import=googleapis.deno.dev,deno.land,jsr.io,esm.sh main.ts", + "dev:frontend": "cd frontend && OLTP_ENDPOINT=http://localhost:4318 deno task dev", + "prod:frontend": "deno run -A --watch ./tools/prod_proxy.ts & cd frontend && API_ROOT=https://api.jsr.io deno task dev", + "lint": "deno task lint:frontend && deno task lint:tools && deno task lint:license", + "lint:frontend": "cd frontend && deno lint && deno check --allow-import=googleapis.deno.dev,deno.land,jsr.io dev.ts main.ts routes/**/*.tsx routes/**/*.ts", + "lint:tools": "deno lint tools/ && deno check --allow-import=googleapis.deno.dev,deno.land,jsr.io tools/**/*.ts", "lint:license": "deno run --allow-read jsr:@kt3k/license-checker@3.2.11/main -q", "lint:license:fix": "deno run --allow-read --allow-write jsr:@kt3k/license-checker@3.2.11/main -q --inject", "tools:orama:package_reindex": "deno run --allow-env --allow-net tools/orama_package_reindex.ts", @@ -34,15 +35,14 @@ "target/", "api/testdata/", ".gcs/", - "frontend/_fresh" + "frontend/_fresh", + "e2e/vendor" ], - "compilerOptions": { - "jsx": "react-jsx", - "jsxImportSource": "npm:preact" - }, "imports": { - "@deno/gfm": "jsr:@deno/gfm@^0.8.0", - "github-slugger": "npm:github-slugger@^2.0", - "std/": "https://deno.land/std@0.219.0/" + "@deno/gfm": "jsr:@deno/gfm@^0.10.0", + "@std/async": "jsr:@std/async@^1.0.8", + "@std/front-matter": "jsr:@std/front-matter@^1.0.5", + "@std/path": "jsr:@std/path@^1.0.8", + "github-slugger": "npm:github-slugger@^2.0.0" } } diff --git a/deno.lock b/deno.lock index a617b0e4..5ad1a6c2 100644 --- a/deno.lock +++ b/deno.lock @@ -1,24 +1,29 @@ { "version": "4", "specifiers": { - "jsr:@deno/gfm@0.8": "0.8.2", + "jsr:@deno/gfm@0.10": "0.10.0", "jsr:@denosaurs/emoji@0.3": "0.3.1", - "jsr:@std/collections@*": "1.0.8", - "npm:@mdn/browser-compat-data@*": "5.6.9", + "jsr:@std/async@^1.0.8": "1.0.8", + "jsr:@std/collections@*": "1.0.9", + "jsr:@std/collections@^1.0.5": "1.0.9", + "jsr:@std/front-matter@^1.0.5": "1.0.5", + "jsr:@std/path@^1.0.8": "1.0.8", + "jsr:@std/toml@^1.0.1": "1.0.1", + "jsr:@std/yaml@^1.0.5": "1.0.5", + "npm:@mdn/browser-compat-data@*": "5.6.13", "npm:github-slugger@2": "2.0.0", "npm:he@^1.2.0": "1.2.0", "npm:katex@0.16": "0.16.11", - "npm:marked-alert@2": "2.1.0_marked@12.0.2", + "npm:marked-alert@2": "2.1.2_marked@12.0.2", "npm:marked-footnote@^1.2.0": "1.2.4_marked@12.0.2", "npm:marked-gfm-heading-id@^3.1.0": "3.2.0_marked@12.0.2", "npm:marked@12": "12.0.2", - "npm:preact@*": "10.24.3", "npm:prismjs@^1.29.0": "1.29.0", - "npm:sanitize-html@^2.11.0": "2.13.1" + "npm:sanitize-html@^2.13.0": "2.13.1" }, "jsr": { - "@deno/gfm@0.8.2": { - "integrity": "a7528367cbd954a2d0de316bd0097ee92f06d2cb66502c8574de133ed223424f", + "@deno/gfm@0.10.0": { + "integrity": "51708205e3559a4aeb6afb29d07c5bfafe7941f91bb360351ef6621de9a39527", "dependencies": [ "jsr:@denosaurs/emoji", "npm:github-slugger", @@ -35,13 +40,35 @@ "@denosaurs/emoji@0.3.1": { "integrity": "b0aed5f55dec99e83da7c9637fe0a36d1d6252b7c99deaaa3fc5dea3fcf3da8b" }, - "@std/collections@1.0.8": { - "integrity": "de76692f9121838711b1d2fb5042619c074db26905a87b58cff56cfe1bd6d6d0" + "@std/async@1.0.8": { + "integrity": "c057c5211a0f1d12e7dcd111ab430091301b8d64b4250052a79d277383bc3ba7" + }, + "@std/collections@1.0.9": { + "integrity": "4f58104ead08a04a2199374247f07befe50ba01d9cca8cbb23ab9a0419921e71" + }, + "@std/front-matter@1.0.5": { + "integrity": "abddc64030a33eb5bc524b8c73e7c417cea09177aaeb4abf75a56b540c4b6e60", + "dependencies": [ + "jsr:@std/toml", + "jsr:@std/yaml" + ] + }, + "@std/path@1.0.8": { + "integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be" + }, + "@std/toml@1.0.1": { + "integrity": "b55b407159930f338d384b1f8fd317c8e8a35e27ebb8946155f49e3a158d16c4", + "dependencies": [ + "jsr:@std/collections@^1.0.5" + ] + }, + "@std/yaml@1.0.5": { + "integrity": "71ba3d334305ee2149391931508b2c293a8490f94a337eef3a09cade1a2a2742" } }, "npm": { - "@mdn/browser-compat-data@5.6.9": { - "integrity": "sha512-xbpYnhcx48qe1p8qimSCUu79QPhK6STaj5mUJ7A0VRCxgfZ5boJ4L/Vy9e5lOPquPSQ1tWZ6mOO+01VzLJg2iA==" + "@mdn/browser-compat-data@5.6.13": { + "integrity": "sha512-eZOraBiugKZewtS10c7M78OKwL6CBhVzqSQvb5j+WGw/7MdPRfHrP7LuiEoLCeHXfmE414geJjnHPGQ0iAnCyg==" }, "commander@8.3.0": { "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" @@ -104,8 +131,8 @@ "commander" ] }, - "marked-alert@2.1.0_marked@12.0.2": { - "integrity": "sha512-X95Z8PCDgWa0bBfM70GxZG3LD/leUrhXc3cx3w1eFExBhswd1oXn/S4S+9H8ypPdCY7okREb4dItUOc+VJq4jQ==", + "marked-alert@2.1.2_marked@12.0.2": { + "integrity": "sha512-EFNRZ08d8L/iEIPLTlQMDjvwIsj03gxWCczYTht6DCiHJIZhMk4NK5gtPY9UqAYb09eV5VGT+jD4lp396E0I+w==", "dependencies": [ "marked" ] @@ -143,9 +170,6 @@ "source-map-js" ] }, - "preact@10.24.3": { - "integrity": "sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==" - }, "prismjs@1.29.0": { "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==" }, @@ -268,121 +292,6 @@ "https://deno.land/std@0.214.0/path/windows/separator.ts": "e51c5522140eff4f8402617c5c68a201fdfa3a1a8b28dc23587cff931b665e43", "https://deno.land/std@0.214.0/path/windows/to_file_url.ts": "1cd63fd35ec8d1370feaa4752eccc4cc05ea5362a878be8dc7db733650995484", "https://deno.land/std@0.214.0/path/windows/to_namespaced_path.ts": "4ffa4fb6fae321448d5fe810b3ca741d84df4d7897e61ee29be961a6aac89a4c", - "https://deno.land/std@0.219.0/assert/assert.ts": "bec068b2fccdd434c138a555b19a2c2393b71dfaada02b7d568a01541e67cdc5", - "https://deno.land/std@0.219.0/assert/assertion_error.ts": "9f689a101ee586c4ce92f52fa7ddd362e86434ffdf1f848e45987dc7689976b8", - "https://deno.land/std@0.219.0/async/pool.ts": "2b972e3643444b73f6a8bcdd19799a2d0821b28a45fbe47fd333223eb84327f0", - "https://deno.land/std@0.219.0/front_matter/_formats.ts": "2f865e89ba30d65bdb64e3fd7fdb162735511c20d0a61e8325c411498689e130", - "https://deno.land/std@0.219.0/front_matter/create_extractor.ts": "ee1c398d8d214b99e9d00f509f6a15bb8b2839b38b2fcd0efc1105c87034fb72", - "https://deno.land/std@0.219.0/front_matter/yaml.ts": "64ac11012943a38250b32567be3330dd2a8dac81afcf5d1afa4ac564090f3ca3", - "https://deno.land/std@0.219.0/path/_common/assert_path.ts": "dbdd757a465b690b2cc72fc5fb7698c51507dec6bfafce4ca500c46b76ff7bd8", - "https://deno.land/std@0.219.0/path/_common/basename.ts": "569744855bc8445f3a56087fd2aed56bdad39da971a8d92b138c9913aecc5fa2", - "https://deno.land/std@0.219.0/path/_common/common.ts": "ef73c2860694775fe8ffcbcdd387f9f97c7a656febf0daa8c73b56f4d8a7bd4c", - "https://deno.land/std@0.219.0/path/_common/constants.ts": "dc5f8057159f4b48cd304eb3027e42f1148cf4df1fb4240774d3492b5d12ac0c", - "https://deno.land/std@0.219.0/path/_common/dirname.ts": "684df4aa71a04bbcc346c692c8485594fc8a90b9408dfbc26ff32cf3e0c98cc8", - "https://deno.land/std@0.219.0/path/_common/format.ts": "92500e91ea5de21c97f5fe91e178bae62af524b72d5fcd246d6d60ae4bcada8b", - "https://deno.land/std@0.219.0/path/_common/from_file_url.ts": "d672bdeebc11bf80e99bf266f886c70963107bdd31134c4e249eef51133ceccf", - "https://deno.land/std@0.219.0/path/_common/glob_to_reg_exp.ts": "6cac16d5c2dc23af7d66348a7ce430e5de4e70b0eede074bdbcf4903f4374d8d", - "https://deno.land/std@0.219.0/path/_common/normalize.ts": "684df4aa71a04bbcc346c692c8485594fc8a90b9408dfbc26ff32cf3e0c98cc8", - "https://deno.land/std@0.219.0/path/_common/normalize_string.ts": "dfdf657a1b1a7db7999f7c575ee7e6b0551d9c20f19486c6c3f5ff428384c965", - "https://deno.land/std@0.219.0/path/_common/relative.ts": "faa2753d9b32320ed4ada0733261e3357c186e5705678d9dd08b97527deae607", - "https://deno.land/std@0.219.0/path/_common/strip_trailing_separators.ts": "7024a93447efcdcfeaa9339a98fa63ef9d53de363f1fbe9858970f1bba02655a", - "https://deno.land/std@0.219.0/path/_common/to_file_url.ts": "7f76adbc83ece1bba173e6e98a27c647712cab773d3f8cbe0398b74afc817883", - "https://deno.land/std@0.219.0/path/_interface.ts": "a1419fcf45c0ceb8acdccc94394e3e94f99e18cfd32d509aab514c8841799600", - "https://deno.land/std@0.219.0/path/_os.ts": "8fb9b90fb6b753bd8c77cfd8a33c2ff6c5f5bc185f50de8ca4ac6a05710b2c15", - "https://deno.land/std@0.219.0/path/basename.ts": "5d341aadb7ada266e2280561692c165771d071c98746fcb66da928870cd47668", - "https://deno.land/std@0.219.0/path/common.ts": "03e52e22882402c986fe97ca3b5bb4263c2aa811c515ce84584b23bac4cc2643", - "https://deno.land/std@0.219.0/path/constants.ts": "0c206169ca104938ede9da48ac952de288f23343304a1c3cb6ec7625e7325f36", - "https://deno.land/std@0.219.0/path/dirname.ts": "85bd955bf31d62c9aafdd7ff561c4b5fb587d11a9a5a45e2b01aedffa4238a7c", - "https://deno.land/std@0.219.0/path/extname.ts": "593303db8ae8c865cbd9ceec6e55d4b9ac5410c1e276bfd3131916591b954441", - "https://deno.land/std@0.219.0/path/format.ts": "42a2f3201343df77061207e6aaf78c95bafce7f711dcb7fe1e5840311c505778", - "https://deno.land/std@0.219.0/path/from_file_url.ts": "911833ae4fd10a1c84f6271f36151ab785955849117dc48c6e43b929504ee069", - "https://deno.land/std@0.219.0/path/glob_to_regexp.ts": "7f30f0a21439cadfdae1be1bf370880b415e676097fda584a63ce319053b5972", - "https://deno.land/std@0.219.0/path/is_absolute.ts": "4791afc8bfd0c87f0526eaa616b0d16e7b3ab6a65b62942e50eac68de4ef67d7", - "https://deno.land/std@0.219.0/path/is_glob.ts": "a65f6195d3058c3050ab905705891b412ff942a292bcbaa1a807a74439a14141", - "https://deno.land/std@0.219.0/path/join.ts": "ae2ec5ca44c7e84a235fd532e4a0116bfb1f2368b394db1c4fb75e3c0f26a33a", - "https://deno.land/std@0.219.0/path/join_globs.ts": "5b3bf248b93247194f94fa6947b612ab9d3abd571ca8386cf7789038545e54a0", - "https://deno.land/std@0.219.0/path/mod.ts": "2821a1bb3a4148a0ffe79c92aa41aa9319fef73c6d6f5178f52b2c720d3eb02d", - "https://deno.land/std@0.219.0/path/normalize.ts": "4155743ccceeed319b350c1e62e931600272fad8ad00c417b91df093867a8352", - "https://deno.land/std@0.219.0/path/normalize_glob.ts": "cc89a77a7d3b1d01053b9dcd59462b75482b11e9068ae6c754b5cf5d794b374f", - "https://deno.land/std@0.219.0/path/parse.ts": "65e8e285f1a63b714e19ef24b68f56e76934c3df0b6e65fd440d3991f4f8aefb", - "https://deno.land/std@0.219.0/path/posix/_util.ts": "1e3937da30f080bfc99fe45d7ed23c47dd8585c5e473b2d771380d3a6937cf9d", - "https://deno.land/std@0.219.0/path/posix/basename.ts": "39ee27a29f1f35935d3603ccf01d53f3d6e0c5d4d0f84421e65bd1afeff42843", - "https://deno.land/std@0.219.0/path/posix/common.ts": "26f60ccc8b2cac3e1613000c23ac5a7d392715d479e5be413473a37903a2b5d4", - "https://deno.land/std@0.219.0/path/posix/constants.ts": "93481efb98cdffa4c719c22a0182b994e5a6aed3047e1962f6c2c75b7592bef1", - "https://deno.land/std@0.219.0/path/posix/dirname.ts": "6535d2bdd566118963537b9dda8867ba9e2a361015540dc91f5afbb65c0cce8b", - "https://deno.land/std@0.219.0/path/posix/extname.ts": "8d36ae0082063c5e1191639699e6f77d3acf501600a3d87b74943f0ae5327427", - "https://deno.land/std@0.219.0/path/posix/format.ts": "185e9ee2091a42dd39e2a3b8e4925370ee8407572cee1ae52838aed96310c5c1", - "https://deno.land/std@0.219.0/path/posix/from_file_url.ts": "951aee3a2c46fd0ed488899d024c6352b59154c70552e90885ed0c2ab699bc40", - "https://deno.land/std@0.219.0/path/posix/glob_to_regexp.ts": "76f012fcdb22c04b633f536c0b9644d100861bea36e9da56a94b9c589a742e8f", - "https://deno.land/std@0.219.0/path/posix/is_absolute.ts": "cebe561ad0ae294f0ce0365a1879dcfca8abd872821519b4fcc8d8967f888ede", - "https://deno.land/std@0.219.0/path/posix/is_glob.ts": "8a8b08c08bf731acf2c1232218f1f45a11131bc01de81e5f803450a5914434b9", - "https://deno.land/std@0.219.0/path/posix/join.ts": "744fadcbee7047688696455c7cbb368a9625ffde67fc3058a61c98948fcd04de", - "https://deno.land/std@0.219.0/path/posix/join_globs.ts": "a9475b44645feddceb484ee0498e456f4add112e181cb94042cdc6d47d1cdd25", - "https://deno.land/std@0.219.0/path/posix/mod.ts": "2301fc1c54a28b349e20656f68a85f75befa0ee9b6cd75bfac3da5aca9c3f604", - "https://deno.land/std@0.219.0/path/posix/normalize.ts": "baeb49816a8299f90a0237d214cef46f00ba3e95c0d2ceb74205a6a584b58a91", - "https://deno.land/std@0.219.0/path/posix/normalize_glob.ts": "9c87a829b6c0f445d03b3ecadc14492e2864c3ebb966f4cea41e98326e4435c6", - "https://deno.land/std@0.219.0/path/posix/parse.ts": "0b1fc4cb890dbb699ec1d2c232d274843b4a7142e1ad976b69fe51c954eb6080", - "https://deno.land/std@0.219.0/path/posix/relative.ts": "3907d6eda41f0ff723d336125a1ad4349112cd4d48f693859980314d5b9da31c", - "https://deno.land/std@0.219.0/path/posix/resolve.ts": "08b699cfeee10cb6857ccab38fa4b2ec703b0ea33e8e69964f29d02a2d5257cf", - "https://deno.land/std@0.219.0/path/posix/to_file_url.ts": "7aa752ba66a35049e0e4a4be5a0a31ac6b645257d2e031142abb1854de250aaf", - "https://deno.land/std@0.219.0/path/posix/to_namespaced_path.ts": "28b216b3c76f892a4dca9734ff1cc0045d135532bfd9c435ae4858bfa5a2ebf0", - "https://deno.land/std@0.219.0/path/relative.ts": "ab739d727180ed8727e34ed71d976912461d98e2b76de3d3de834c1066667add", - "https://deno.land/std@0.219.0/path/resolve.ts": "a6f977bdb4272e79d8d0ed4333e3d71367cc3926acf15ac271f1d059c8494d8d", - "https://deno.land/std@0.219.0/path/to_file_url.ts": "88f049b769bce411e2d2db5bd9e6fd9a185a5fbd6b9f5ad8f52bef517c4ece1b", - "https://deno.land/std@0.219.0/path/to_namespaced_path.ts": "b706a4103b104cfadc09600a5f838c2ba94dbcdb642344557122dda444526e40", - "https://deno.land/std@0.219.0/path/windows/_util.ts": "d5f47363e5293fced22c984550d5e70e98e266cc3f31769e1710511803d04808", - "https://deno.land/std@0.219.0/path/windows/basename.ts": "e2dbf31d1d6385bfab1ce38c333aa290b6d7ae9e0ecb8234a654e583cf22f8fe", - "https://deno.land/std@0.219.0/path/windows/common.ts": "26f60ccc8b2cac3e1613000c23ac5a7d392715d479e5be413473a37903a2b5d4", - "https://deno.land/std@0.219.0/path/windows/constants.ts": "5afaac0a1f67b68b0a380a4ef391bf59feb55856aa8c60dfc01bd3b6abb813f5", - "https://deno.land/std@0.219.0/path/windows/dirname.ts": "33e421be5a5558a1346a48e74c330b8e560be7424ed7684ea03c12c21b627bc9", - "https://deno.land/std@0.219.0/path/windows/extname.ts": "165a61b00d781257fda1e9606a48c78b06815385e7d703232548dbfc95346bef", - "https://deno.land/std@0.219.0/path/windows/format.ts": "bbb5ecf379305b472b1082cd2fdc010e44a0020030414974d6029be9ad52aeb6", - "https://deno.land/std@0.219.0/path/windows/from_file_url.ts": "ced2d587b6dff18f963f269d745c4a599cf82b0c4007356bd957cb4cb52efc01", - "https://deno.land/std@0.219.0/path/windows/glob_to_regexp.ts": "e45f1f89bf3fc36f94ab7b3b9d0026729829fabc486c77f414caebef3b7304f8", - "https://deno.land/std@0.219.0/path/windows/is_absolute.ts": "4a8f6853f8598cf91a835f41abed42112cebab09478b072e4beb00ec81f8ca8a", - "https://deno.land/std@0.219.0/path/windows/is_glob.ts": "8a8b08c08bf731acf2c1232218f1f45a11131bc01de81e5f803450a5914434b9", - "https://deno.land/std@0.219.0/path/windows/join.ts": "8d03530ab89195185103b7da9dfc6327af13eabdcd44c7c63e42e27808f50ecf", - "https://deno.land/std@0.219.0/path/windows/join_globs.ts": "a9475b44645feddceb484ee0498e456f4add112e181cb94042cdc6d47d1cdd25", - "https://deno.land/std@0.219.0/path/windows/mod.ts": "2301fc1c54a28b349e20656f68a85f75befa0ee9b6cd75bfac3da5aca9c3f604", - "https://deno.land/std@0.219.0/path/windows/normalize.ts": "78126170ab917f0ca355a9af9e65ad6bfa5be14d574c5fb09bb1920f52577780", - "https://deno.land/std@0.219.0/path/windows/normalize_glob.ts": "9c87a829b6c0f445d03b3ecadc14492e2864c3ebb966f4cea41e98326e4435c6", - "https://deno.land/std@0.219.0/path/windows/parse.ts": "dbdfe2bc6db482d755b5f63f7207cd019240fcac02ad2efa582adf67ff10553a", - "https://deno.land/std@0.219.0/path/windows/relative.ts": "3e1abc7977ee6cc0db2730d1f9cb38be87b0ce4806759d271a70e4997fc638d7", - "https://deno.land/std@0.219.0/path/windows/resolve.ts": "8dae1dadfed9d46ff46cc337c9525c0c7d959fb400a6308f34595c45bdca1972", - "https://deno.land/std@0.219.0/path/windows/to_file_url.ts": "40e560ee4854fe5a3d4d12976cef2f4e8914125c81b11f1108e127934ced502e", - "https://deno.land/std@0.219.0/path/windows/to_namespaced_path.ts": "4ffa4fb6fae321448d5fe810b3ca741d84df4d7897e61ee29be961a6aac89a4c", - "https://deno.land/std@0.219.0/yaml/_error.ts": "f38cdebdb69cde16903d9aa2f3b8a3dd9d13e5f7f3570bf662bfaca69fef669e", - "https://deno.land/std@0.219.0/yaml/_loader/loader.ts": "959c2ab7bbf5fb565bc3f3344f5e92b2712d39ea77a1e57039591696335c6d29", - "https://deno.land/std@0.219.0/yaml/_loader/loader_state.ts": "ee216de6040551940b85473c3185fdb7a6f3030b77153f87a6b7f63f82e489ea", - "https://deno.land/std@0.219.0/yaml/_mark.ts": "1d9d071f8c62d19f284ca4a5aae41680e67653a06a2a4b0eccf931fc5719afa1", - "https://deno.land/std@0.219.0/yaml/_state.ts": "f3b1c1fd11860302f1f33e35e9ce089bf069d4943e8d67516cd6bedbba058c13", - "https://deno.land/std@0.219.0/yaml/_type/binary.ts": "26216e8f306e62401ba00e306e93cdd5fb88da361cdaa567e63ee216dc3ebf93", - "https://deno.land/std@0.219.0/yaml/_type/bool.ts": "121743b23ba82a27ad6a3ec6298c7f5b0908f90e52707f8644a91f7ad51ed2ef", - "https://deno.land/std@0.219.0/yaml/_type/float.ts": "73295b7d8cc24edadfea5041e2255a6332e3491715e884e3bb7d03b563a90a81", - "https://deno.land/std@0.219.0/yaml/_type/function.ts": "bbf705058942bf3370604b37eb77a10aadd72f986c237c9f69b43378a42202c1", - "https://deno.land/std@0.219.0/yaml/_type/int.ts": "c2dc88438a60fccc8d2226042bd18b9967753adaf6bd145feb8b99d567e432ce", - "https://deno.land/std@0.219.0/yaml/_type/map.ts": "ae2acb1cb837fb8e96c75c98611cfd45af847d0114ab5336333c318e7d4b12f4", - "https://deno.land/std@0.219.0/yaml/_type/merge.ts": "ad0d971f91d2fb9f4ab3eba0c837eae357b1804d6b798adc99dc917bc5306b11", - "https://deno.land/std@0.219.0/yaml/_type/mod.ts": "e8929d7b1c969a74f76338d4eb380ef8c4a26cd6441117d521f076b766e9c265", - "https://deno.land/std@0.219.0/yaml/_type/nil.ts": "cbe4387d02d5933322c21b25d8955c5e6228c492e391a6fb82dcf4f498cc421c", - "https://deno.land/std@0.219.0/yaml/_type/omap.ts": "cda915105ab22ba9e1d6317adacee8eec2d8ddaf864cc2f814e3e476946e72c6", - "https://deno.land/std@0.219.0/yaml/_type/pairs.ts": "f97d7dc2b3fa18e246763f44147f6df0d6036c7e122af3e7b6692e4a6b0e289f", - "https://deno.land/std@0.219.0/yaml/_type/regexp.ts": "e49eb9e1c9356fd142bc15f7f323820d411fcc537b5ba3896df9a8b812d270a4", - "https://deno.land/std@0.219.0/yaml/_type/seq.ts": "2deffc7f970869bc01a1541b4961d076329a1c2b30b95e07918f3132db7c3fe2", - "https://deno.land/std@0.219.0/yaml/_type/set.ts": "be8a9e7237a7ffc92dfbe7f5e552d84b7eeba60f3f73cc77fc3c59d3506c74ea", - "https://deno.land/std@0.219.0/yaml/_type/str.ts": "88f0a1ba12295520cd57e96cd78d53aa0787d53c7a1c506155f418c496c2f550", - "https://deno.land/std@0.219.0/yaml/_type/timestamp.ts": "57a6bb4a0f0bd5eab85a1f0ee5ac8820fd3125ea939dc8a037de997a2b6ad05d", - "https://deno.land/std@0.219.0/yaml/_type/undefined.ts": "9d215953c65740f1764e0bdca021007573473f0c49e087f00d9ff02817ecfc97", - "https://deno.land/std@0.219.0/yaml/_utils.ts": "91bbe28b5e7000b9594e40ff5353f8fe7a7ba914eec917e1202cbaf5ac931c58", - "https://deno.land/std@0.219.0/yaml/parse.ts": "f45278d9ebccb789af4eceeffa5c291e194bcf1fa9aab1b34ff52c2bd4a9d886", - "https://deno.land/std@0.219.0/yaml/schema.ts": "dae089ffa1ac4a2b031176aa019e126be6f7230a3011de38463ead8639b14739", - "https://deno.land/std@0.219.0/yaml/schema/core.ts": "1222f9401e2a0c1d38e63d753da98be333e61a6032335e9c46a68bd45ecce85a", - "https://deno.land/std@0.219.0/yaml/schema/default.ts": "b77c71cfd453951dd828e5f2f02f9f37335c9c0a49c8051d1a9653fa82357740", - "https://deno.land/std@0.219.0/yaml/schema/extended.ts": "996da59626409047b5c1a2d68bdbeead43914cedede47c5923e80ae4febe7d24", - "https://deno.land/std@0.219.0/yaml/schema/failsafe.ts": "24b2b630cef6fcce7de6d29db651523b0f49e5691d690931c42ecf4823837fdb", - "https://deno.land/std@0.219.0/yaml/schema/json.ts": "0fb9268282d266c24d963e75ef77f51accbbb74f40713a99e83ad621a81bc9ae", - "https://deno.land/std@0.219.0/yaml/schema/mod.ts": "9bf7ff80c2a246f781bdcab979211d0389760831a974cf5883bf2016567e3507", - "https://deno.land/std@0.219.0/yaml/type.ts": "708dde5f20b01cc1096489b7155b6af79a217d585afb841128e78c3c2391eb5c", "https://deno.land/x/deno_doc@0.100.0/deno_doc_wasm.generated.js": "a8011ac4b2d7b704b36d4a2b32d021cba5ea2a796d60ea74870d5f88573fb639", "https://deno.land/x/deno_doc@0.100.0/mod.ts": "3a1069e65428ddadabcf717c40b23805f309514edb3a984090eee037a91c17a9", "https://deno.land/x/deno_graph@0.64.1/deno_graph_wasm.generated.js": "f34428e40b5c7b91ce7a05734d6782a83848cbb7f9f6510a4226d7c8b8ca2d8d", @@ -391,82 +300,6 @@ "https://deno.land/x/deno_graph@0.64.1/mod.ts": "c1d12418cfb7c2f913b18a612806c79742ae4917dff70a8326abf009692dbcaf", "https://deno.land/x/deno_graph@0.64.1/types.ts": "bde84cb2919068c07e6cf4d8bf3054e8da908f2f221623d5302380df29b96320", "https://deno.land/x/dir@1.5.1/data_local_dir/mod.ts": "91eb1c4bfadfbeda30171007bac6d85aadacd43224a5ed721bbe56bc64e9eb66", - "https://deno.land/x/jose@v4.4.0/index.ts": "e77ff3af7f89af2eb83785b032c3850657e62873a26b75201df6d35f5535a2ec", - "https://deno.land/x/jose@v4.4.0/jwe/compact/decrypt.ts": "bbeb5e54a75696d45e6957dc37ae2d934dbac4ab4de0f0486df3aac96e3272a3", - "https://deno.land/x/jose@v4.4.0/jwe/compact/encrypt.ts": "844f20b4a73dc9b059f23e58a972734a04a2e5eef58564a076c3576c0417a47d", - "https://deno.land/x/jose@v4.4.0/jwe/flattened/decrypt.ts": "03e1151e10c01aa3adf6c83c7872e0189cf88842ed972aa77c3ba7a14476339b", - "https://deno.land/x/jose@v4.4.0/jwe/flattened/encrypt.ts": "d45e3bd297aba71b737071b26684e050f1956d7a5981e2a0aaddc4c168ceb2c2", - "https://deno.land/x/jose@v4.4.0/jwe/general/decrypt.ts": "4e213af3c0709719e10b9c97a7f618d4301e92b062e6b2e63cc7039e3ae5fe59", - "https://deno.land/x/jose@v4.4.0/jwe/general/encrypt.ts": "3a8a92542b87174bd3ae89006c62289dd17e9b571de79b3c3c2a7bdc0b319981", - "https://deno.land/x/jose@v4.4.0/jwk/embedded.ts": "a01423282dc918e2fc9ccf05cd71ef1ff24aa4ad15d10a5ec39ae4e1e4e5fd8e", - "https://deno.land/x/jose@v4.4.0/jwk/thumbprint.ts": "86db2e797453c76b661c1096e2979187fd00a6061566f35e2404d09934ef4361", - "https://deno.land/x/jose@v4.4.0/jwks/local.ts": "d0c25348bee22cc68b513ee68049c663c90e25c9a1377142d4a5eab5bebfa5aa", - "https://deno.land/x/jose@v4.4.0/jwks/remote.ts": "fe1814050fb480650e477ba0578da1b6c8f76a3d7b730ca16cbaee42fdd9e607", - "https://deno.land/x/jose@v4.4.0/jws/compact/sign.ts": "2230dbb7e92dd507a2c2b0902d55a8f968a7adf008d27a8234ace10bc2900bdd", - "https://deno.land/x/jose@v4.4.0/jws/compact/verify.ts": "c11b7b082b188e9ece52d22c850031cc3e4aff4a1f129e715ee0d222dd2c435f", - "https://deno.land/x/jose@v4.4.0/jws/flattened/sign.ts": "2a16a77c309b89d552a35e6ea2f99bc3634171b07a66e8e5f7092e324a901998", - "https://deno.land/x/jose@v4.4.0/jws/flattened/verify.ts": "be16b075d71c47295e702ddf4273a6a2847e003acdb7e7ac3d69c11da048953a", - "https://deno.land/x/jose@v4.4.0/jws/general/sign.ts": "962cda55a297911ecca284e43f95768156b7d1ee9902cb095ad1a7cc1839a7bd", - "https://deno.land/x/jose@v4.4.0/jws/general/verify.ts": "ce4b5d506b4d08d21f73752f322e0dd63571989c3e310228751540d8c341edc0", - "https://deno.land/x/jose@v4.4.0/jwt/decrypt.ts": "a3ec706ee5ba19e6a0f9220aa5b62bd86a8ab5a87bcbd2112a639ed1259d3659", - "https://deno.land/x/jose@v4.4.0/jwt/encrypt.ts": "ccbc830865b59264b8d48c1d9a440cd525507cd9994d22e718337c670d71c231", - "https://deno.land/x/jose@v4.4.0/jwt/produce.ts": "8affc83f934ea721037d58f238cc23e30c0381838ae1b8dc668b499f8b5e1084", - "https://deno.land/x/jose@v4.4.0/jwt/sign.ts": "c27dc85eb671a4acd91e3090f981f335bbc4387bd8b917df8750cd77d6862a61", - "https://deno.land/x/jose@v4.4.0/jwt/unsecured.ts": "df310e874020119937767596cc7698da227dc18a7ef72e5fe4f49133ed183974", - "https://deno.land/x/jose@v4.4.0/jwt/verify.ts": "c66a7ef0a136847bb39b25bfcc3ee42cfe9b8722faf6d8503556a3f6f38e4fbe", - "https://deno.land/x/jose@v4.4.0/key/export.ts": "b0806846a4ebd02c23a569f604cc07fb218e81fe51ed4ae3350e524798887668", - "https://deno.land/x/jose@v4.4.0/key/generate_key_pair.ts": "ee81d38d51eda55f40fdf86ff37c66f577ff38776d75b34fe8d47d4e1d60d32a", - "https://deno.land/x/jose@v4.4.0/key/generate_secret.ts": "6864e16d654c44db68dce2b092c3162f8ae33ebd0720fedb92426a452141f759", - "https://deno.land/x/jose@v4.4.0/key/import.ts": "9c3249047571cea9753be4aeaf7d27fd5ada258c22997c671847eaa86be23fac", - "https://deno.land/x/jose@v4.4.0/lib/aesgcmkw.ts": "9415c556597be41a4a2f7203fd32fb00d1f06b6b2cfef70d481acec39c7807d6", - "https://deno.land/x/jose@v4.4.0/lib/buffer_utils.ts": "81e8f7212caf9090b13ddc9bfcbfab2d2c23d470ea179158caac21e9575a8ef4", - "https://deno.land/x/jose@v4.4.0/lib/cek.ts": "a474becfe1c2d86fbcf3a24cdcd96274beb8d61bd17926e5f345001f39df922b", - "https://deno.land/x/jose@v4.4.0/lib/check_iv_length.ts": "118eb531167126c8421d71a21f2cfdc10a658c933e178b33395ef3e962c54f80", - "https://deno.land/x/jose@v4.4.0/lib/check_key_type.ts": "90a5d17a1f8b3fb170847180454f434121605175c3485c8ef67ff73cfb8e7691", - "https://deno.land/x/jose@v4.4.0/lib/check_p2s.ts": "2f5549e121c43019ac85a3bb3fe8cb98a397122dcaa80f3cd8bf5fcf314e1f67", - "https://deno.land/x/jose@v4.4.0/lib/crypto_key.ts": "a4f0ffc10f603417ec4b69bdbb75502b498ba025150e0799e3af073b63c9739c", - "https://deno.land/x/jose@v4.4.0/lib/decrypt_key_management.ts": "2f8cdf423333ef4fb5870a2f1a80558dd017073b0ad4d0c627792824dba91931", - "https://deno.land/x/jose@v4.4.0/lib/encrypt_key_management.ts": "e45d3e433ee30089b487ab9342f1bb331c3e95b8c66e4b0bd14b433f2764ea84", - "https://deno.land/x/jose@v4.4.0/lib/epoch.ts": "cd608f73f6c100e8156c6020ec2bce6757e01759793f0d6aab23908d3d2ea933", - "https://deno.land/x/jose@v4.4.0/lib/format_pem.ts": "b5230682e7a89609238015b77f33afd248f3e0f69bcb5895eece2f86d83100f6", - "https://deno.land/x/jose@v4.4.0/lib/invalid_key_input.ts": "8524ead62c3ecd990824306d47f1b0ce9a98a85ef55ffaee201d185b7c89edf4", - "https://deno.land/x/jose@v4.4.0/lib/is_disjoint.ts": "b5ea1cb260899f5cfb04f032029956e637067714a275d13be429fc53287a4b17", - "https://deno.land/x/jose@v4.4.0/lib/is_object.ts": "43549ddc51a3b3d4c22b953b191a961fbb61fb5081e8efb88ad075afa1f4d214", - "https://deno.land/x/jose@v4.4.0/lib/iv.ts": "4766d9ad87b478bb7344094f38c8561181b72f8678edd1b5226d1e0f9ab677fc", - "https://deno.land/x/jose@v4.4.0/lib/jwt_claims_set.ts": "a01ee9a7dbfa7fe52edc89380b9c6616ccbafbe0881bfac545e188d76127413a", - "https://deno.land/x/jose@v4.4.0/lib/secs.ts": "03a2f02fda0f76bf431734552a947c2916c699b904ae0d2f90a415931c30e66d", - "https://deno.land/x/jose@v4.4.0/lib/validate_algorithms.ts": "6b20f4b5f6935cd9edcd6eb2128226144ba792eaa7c47966c666a51baf1682eb", - "https://deno.land/x/jose@v4.4.0/lib/validate_crit.ts": "6d2b43959ddf432060505ef13af32cb1bf0daff815ef1eae4d7971629566a695", - "https://deno.land/x/jose@v4.4.0/runtime/aeskw.ts": "a9bd412c6d07b2606520972671a545cdb205f79f0a2e9ec0fb145fb2147319e1", - "https://deno.land/x/jose@v4.4.0/runtime/asn1.ts": "cc7524f4cad655585e184d7c0d961339be5c1f6112fbc185404f6f02cabe533d", - "https://deno.land/x/jose@v4.4.0/runtime/base64url.ts": "3772c03d23a47d5da2b93e11018d1f187894be8902be62f6105f143728185f44", - "https://deno.land/x/jose@v4.4.0/runtime/bogus.ts": "4f1c967b0d9b4e7105e16ad8c173da55708f377ee5e201d8ee5fc613f3417f08", - "https://deno.land/x/jose@v4.4.0/runtime/check_cek_length.ts": "e261c01cb8968c8d30e343729f08f7d25ae637f13eb71f3c17da966d038749e8", - "https://deno.land/x/jose@v4.4.0/runtime/check_key_length.ts": "5656870cc4460602775134280bf46f17e27100b237bdb5c687aceabeffc8f2a2", - "https://deno.land/x/jose@v4.4.0/runtime/decrypt.ts": "fc24eadefce13095a4012972a1552f148d9d12d8ed7d1f17ed7c87e00810335f", - "https://deno.land/x/jose@v4.4.0/runtime/digest.ts": "cee73fad56ce596ffedc56811d174ab413e7981eb847eb67c0e77f213cc2ac2d", - "https://deno.land/x/jose@v4.4.0/runtime/ecdhes.ts": "b18b05b091102e5fd3904b0ea21758c558fde4076840a422e28f305a7a5bf17d", - "https://deno.land/x/jose@v4.4.0/runtime/encrypt.ts": "50d400ab152e2d66bffccf7473545097dd69894bc05508530260c8bc0d811638", - "https://deno.land/x/jose@v4.4.0/runtime/env.ts": "3fc0557269c138427f4c00a1f21bec1474f1bc60e5c5ecc61a217c597c5cc6a9", - "https://deno.land/x/jose@v4.4.0/runtime/fetch_jwks.ts": "28c1008ec28e8a0dd6c4d78313f8f22203593615fa078654a962ede3270162d1", - "https://deno.land/x/jose@v4.4.0/runtime/generate.ts": "f7d7c6324887abc56087e0758c93dbc3150f5e4b4dd8bee17cae0f931afcbcdd", - "https://deno.land/x/jose@v4.4.0/runtime/get_sign_verify_key.ts": "f08a086524491a54fb2a0e203819d4ca2b193444aecf6dfbaf6d400431cb439c", - "https://deno.land/x/jose@v4.4.0/runtime/is_key_like.ts": "d9660a40820d254843721a53b51eb94a4db39a1ee36103ea8c28e2cc2207599b", - "https://deno.land/x/jose@v4.4.0/runtime/jwk_to_key.ts": "7e88708f6abf7a8c0de62f56c4e8af6070ed9aaddb5a42b09639756ef472546c", - "https://deno.land/x/jose@v4.4.0/runtime/key_to_jwk.ts": "2af6f52abbe59316fa96771da48538c8f718b6fdd8703d185f8a87ef44c0f064", - "https://deno.land/x/jose@v4.4.0/runtime/pbes2kw.ts": "9c78df798857cadd2dd237321d71e340c52414c7c6e9513e326c555b1e9ad16a", - "https://deno.land/x/jose@v4.4.0/runtime/random.ts": "3e9c8d08208e5dc186ae659535f0018303ff3b56615335bf0dfb5904fe36aab7", - "https://deno.land/x/jose@v4.4.0/runtime/rsaes.ts": "124b6e87d8569b39d6f550b371303c79e9eb28aa0d9b14025eeaffe50282c987", - "https://deno.land/x/jose@v4.4.0/runtime/sign.ts": "1524f8855538ca5fd607cd681f804ba421b0ec58f562118f3c635324ba053f90", - "https://deno.land/x/jose@v4.4.0/runtime/subtle_dsa.ts": "5579d45bbcd321036fa8c64056fb651bb1af7cf98f036ffc4ba4df7b61f3c8e2", - "https://deno.land/x/jose@v4.4.0/runtime/subtle_rsaes.ts": "26147da83932ebf7266d69ddd408f269395de05ddde64ba4e1585571bb61bd93", - "https://deno.land/x/jose@v4.4.0/runtime/timing_safe_equal.ts": "fc5b3f4132cec56630eac4677fef2b519707a9c6a257f8ae86515b0d86ff5f6b", - "https://deno.land/x/jose@v4.4.0/runtime/verify.ts": "d391e2286b47485247b475016c66999f5146a1cf8331115385a9ba629251c15e", - "https://deno.land/x/jose@v4.4.0/runtime/webcrypto.ts": "7075428072d4f0ff6f5c972975b71a9d730f9765bdbb090ba1bf11df293c7d8d", - "https://deno.land/x/jose@v4.4.0/runtime/zlib.ts": "74a4c85d1a6e523282ae927412d58e6789a8d7264b4e966a7df800a97f28a1e1", - "https://deno.land/x/jose@v4.4.0/util/base64url.ts": "d2567042684de8bf1e4f1ad67be40ab343ee192ddf1cf12ff1d940d6c1fa2bcb", - "https://deno.land/x/jose@v4.4.0/util/decode_protected_header.ts": "00c3e86ec4969829568531ac4c52f79f35193759dcd60782e253b4f5e6ac250e", - "https://deno.land/x/jose@v4.4.0/util/errors.ts": "ca0282ae339b178a26f9e85457f6050993382360ee3bf36dff2379b2ef40b317", "https://deno.land/x/postgres@v0.19.3/client.ts": "d141c65c20484c545a1119c9af7a52dcc24f75c1a5633de2b9617b0f4b2ed5c1", "https://deno.land/x/postgres@v0.19.3/client/error.ts": "05b0e35d65caf0ba21f7f6fab28c0811da83cd8b4897995a2f411c2c83391036", "https://deno.land/x/postgres@v0.19.3/connection/auth.ts": "db15c1659742ef4d2791b32834950278dc7a40cb931f8e434e6569298e58df51", @@ -493,17 +326,14 @@ "https://deno.land/x/wasmbuild@0.15.1/cache.ts": "9d01b5cb24e7f2a942bbd8d14b093751fa690a6cde8e21709ddc97667e6669ed", "https://deno.land/x/wasmbuild@0.15.1/loader.ts": "8c2fc10e21678e42f84c5135d8ab6ab7dc92424c3f05d2354896a29ccfd02a63", "https://deno.land/x/wasmbuild@0.15.4/cache.ts": "9d01b5cb24e7f2a942bbd8d14b093751fa690a6cde8e21709ddc97667e6669ed", - "https://deno.land/x/wasmbuild@0.15.4/loader.ts": "8c2fc10e21678e42f84c5135d8ab6ab7dc92424c3f05d2354896a29ccfd02a63", - "https://googleapis.deno.dev/_/base@v1/auth/authclient.ts": "02fefb7ab7ef45f4d013e3c26368b9910fa628a94379d48fe157bf0ae175afad", - "https://googleapis.deno.dev/_/base@v1/auth/jwt.ts": "60a0ce915278fce4626e856c745ea81452cb47c7877715046b02773472cecf15", - "https://googleapis.deno.dev/_/base@v1/auth/mod.ts": "2564c92422e18c3e714ad829af89ac3c28ae3021c7230fcb6ca3a46edf7efe25", - "https://googleapis.deno.dev/_/base@v1/mod.ts": "dac57a0707677eab2dc10f7d9f620b08c61fe052fb97a26309de4d43e4420180", - "https://googleapis.deno.dev/_/base@v1/util.ts": "255693bf0ffbcaa62b4a20f87057254ed439f32cc50084e01c6fd760c1ddf2ab", - "https://googleapis.deno.dev/v1/cloudtrace:v2.ts": "c7f24ee54fe061127f617f5e7b379d679c413b78bd38b3fbaf5c11f9b2822d15" + "https://deno.land/x/wasmbuild@0.15.4/loader.ts": "8c2fc10e21678e42f84c5135d8ab6ab7dc92424c3f05d2354896a29ccfd02a63" }, "workspace": { "dependencies": [ - "jsr:@deno/gfm@0.8", + "jsr:@deno/gfm@0.10", + "jsr:@std/async@^1.0.8", + "jsr:@std/front-matter@^1.0.5", + "jsr:@std/path@^1.0.8", "npm:github-slugger@2" ] } diff --git a/frontend/Dockerfile b/frontend/Dockerfile index b051dda3..13681490 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,11 +1,13 @@ -FROM denoland/deno:alpine-2.0.3 +FROM denoland/deno:alpine-2.0.5 + WORKDIR /app -RUN mkdir /deno_dir -ENV DENO_DIR /deno_dir COPY . . RUN deno task build -RUN deno cache --allow-import main.ts +RUN rm -rf $DENO_DIR +RUN deno install --allow-import -e main.ts + +RUN timeout 2s deno run -A --cached-only main.ts || true CMD ["run", "-A", "--cached-only", "main.ts"] diff --git a/frontend/README.md b/frontend/README.md deleted file mode 100644 index ec0e33ee..00000000 --- a/frontend/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Fresh project - -Your new Fresh project is ready to go. You can follow the Fresh "Getting -Started" guide here: https://fresh.deno.dev/docs/getting-started - -### Usage - -Make sure to install Deno: https://deno.land/manual/getting_started/installation - -Then start the project: - -``` -deno task start -``` - -This will watch the project directory and restart as necessary. diff --git a/frontend/components/HomepageHero.tsx b/frontend/components/HomepageHero.tsx index 0260e818..c331ea93 100644 --- a/frontend/components/HomepageHero.tsx +++ b/frontend/components/HomepageHero.tsx @@ -1,5 +1,5 @@ // Copyright 2024 the JSR authors. All rights reserved. MIT license. -import { asset, Head } from "$fresh/runtime.ts"; +import { asset } from "fresh/runtime"; import { GlobalSearch } from "../islands/GlobalSearch.tsx"; import { HomepageHeroParticles } from "../islands/HomepageHeroParticles.tsx"; import { AnimatedLogo } from "./AnimatedLogo.tsx"; @@ -28,11 +28,9 @@ export function HomepageHero( class="w-screen -ml-[calc(50vw-50%)] -mt-6 bg-repeat py-32 lg:pt-48 relative before:absolute before:left-0 before:right-0 before:h-32 before:bg-gradient-to-t before:from-white before:bottom-0 before:z-10 before:pointer-events-none" id="particles-js" > - - - - + +

diff --git a/frontend/components/List.tsx b/frontend/components/List.tsx index e50a2dbf..7ea9ca59 100644 --- a/frontend/components/List.tsx +++ b/frontend/components/List.tsx @@ -1,6 +1,5 @@ // Copyright 2024 the JSR authors. All rights reserved. MIT license. import { PaginationData } from "../util.ts"; -import { Head } from "$fresh/src/runtime/head.ts"; import { ChevronRight } from "./icons/ChevronRight.tsx"; import { ComponentChildren } from "preact"; @@ -78,18 +77,6 @@ function Pagination( class="flex items-center justify-between border-t border-jsr-cyan-900/10 bg-white px-4 py-3 sm:px-6" aria-label="Pagination" > - - {hasPrevious && ( - - )} - {hasNext && ( - - )} - -
- {pagination.page > 1 + {hasPrevious ? ( ) : } - {itemsCount >= pagination.limit + {hasNext ? ( - - {hasPrevious && ( - - )} - {hasNext && ( - - )} - - {hasPrevious && ( { + const css = CSS.replaceAll("font-size:16px;", ""); + return { + content: args.text.replace( + "/* During the build process, the @deno/gfm CSS file is injected here. */", + css, + ), + }; + }, +); + +if (Deno.args.includes("build")) { + await builder.build(app); +} else { + await builder.listen(app); +} diff --git a/frontend/fresh.config.ts b/frontend/fresh.config.ts deleted file mode 100644 index 816437ae..00000000 --- a/frontend/fresh.config.ts +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2024 the JSR authors. All rights reserved. MIT license. -import { defineConfig, Plugin, PluginRoute } from "$fresh/server.ts"; -import { asset } from "$fresh/runtime.ts"; -import tailwind from "$fresh/plugins/tailwind.ts"; -import { join } from "$std/path"; -import { CSS } from "$gfm"; - -export default defineConfig({ - plugins: [tailwind(), assetifyCssUrl(), gfmCss()], -}); - -const CSS_URL_REGEX = - /url\((?:(?['"])(?(?:(?!\k|\\).|\\.)*)\k|(?[^'")]*))\)/g; - -// This plugin reads the generated style.css file from tailwind plugin and -// replaces the url() (for font paths) with paths that include asset queries for -// caching and cache busting. -function assetifyCssUrl() { - let outDir: string; - return { - name: "assetify-css-url", - buildStart(config) { - outDir = config.build.outDir; - }, - async buildEnd() { - const stylePath = join(outDir, "static", "styles.css"); - let styleCss = await Deno.readTextFile(stylePath); - styleCss = styleCss.replaceAll(CSS_URL_REGEX, (...args) => { - const groups = args.at(-1) as Record; - let path: string; - if (groups.quoted) { - path = groups.quoted.replaceAll(/\\./g, (s) => JSON.parse(`"${s}"`)); - } else { - path = groups.unquoted; - } - return `url(${JSON.stringify(asset(path))})`; - }); - await Deno.writeTextFile(stylePath, styleCss); - }, - } satisfies Plugin; -} - -function gfmCss() { - const patchedCSS = CSS.replaceAll("font-size:16px;", ""); - const css = /*css*/ `${patchedCSS} -.markdown-body { - line-height: 1.6; - overflow: visible; -} - -.markdown-body a { - text-decoration: underline; -} - -.markdown-body :where(b, strong) { - font-weight: 650; -} - -.markdown-body ul { - list-style: disc; -} -.markdown-body ol { - list-style: numeric; -} - -@media screen and (max-width: 768px) { - .markdown-body pre, - .markdown-body .highlight pre { - border-left: 0; - border-right: 0; - border-radius: 0; - } - - .markdown-body pre { - margin-inline: -1rem; - } -} - -@media screen and (max-width: 1024px) { - .markdown-body.break pre > code { - white-space: break-spaces; - word-break: break-word; - } -} - -.markdown-body table { - width: fit-content; -} - -.markdown-body h2 { - padding-bottom: 0.375em; -} - -.markdown-body h2, -.markdown-body h3 { - margin-top: 2em; -} - -.markdown-body pre { - border: 1.5px solid #cbd5e1; -} - -@media screen and (min-width: 1024px) { - .markdown-body .highlight pre, - .markdown-body pre { - padding: 1.5rem; - } -} - -.markdown-body blockquote { - padding: 1.5rem; - background: #f1f5f9; /* cyan-200 */ -} - -.markdown-body p, -.markdown-body blockquote, -.markdown-body ul, -.markdown-body ol, -.markdown-body dl, -.markdown-body table, -.markdown-body pre, -.markdown-body details, -.markdown-body .highlight { - margin-bottom: 1.25rem; -} -`; - - let isDev = false; - - return { - name: "gfm-css", - configResolved(config) { - isDev = config.dev; - }, - async buildStart(config) { - const outDir = config.build.outDir; - const stylePath = join(outDir, "static", "gfm.css"); - await Deno.writeTextFile(stylePath, css); - }, - get routes() { - if (!isDev) return []; - return [ - { - path: "/gfm.css", - handler: () => - new Response(css, { headers: { "content-type": "text/css" } }), - } satisfies PluginRoute, - ]; - }, - } satisfies Plugin; -} diff --git a/frontend/fresh.gen.ts b/frontend/fresh.gen.ts deleted file mode 100644 index 8846aeb2..00000000 --- a/frontend/fresh.gen.ts +++ /dev/null @@ -1,173 +0,0 @@ -// DO NOT EDIT. This file is generated by Fresh. -// This file SHOULD be checked into source version control. -// This file is automatically updated during development when running `dev.ts`. - -import * as $_scope_index from "./routes/@[scope]/index.tsx"; -import * as $_scope_index_1 from "./routes/@[scope]/~/index.tsx"; -import * as $_scope_members from "./routes/@[scope]/~/members.tsx"; -import * as $_scope_settings from "./routes/@[scope]/~/settings.tsx"; -import * as $_404 from "./routes/_404.tsx"; -import * as $_500 from "./routes/_500.tsx"; -import * as $_app from "./routes/_app.tsx"; -import * as $_layout from "./routes/_layout.tsx"; -import * as $_middleware from "./routes/_middleware.ts"; -import * as $account_index from "./routes/account/index.tsx"; -import * as $account_invites from "./routes/account/invites.tsx"; -import * as $account_settings from "./routes/account/settings.tsx"; -import * as $account_tokens_create from "./routes/account/tokens/create.tsx"; -import * as $account_tokens_index from "./routes/account/tokens/index.tsx"; -import * as $admin_middleware from "./routes/admin/_middleware.ts"; -import * as $admin_index from "./routes/admin/index.tsx"; -import * as $admin_publishingTasks from "./routes/admin/publishingTasks.tsx"; -import * as $admin_scopes_assign from "./routes/admin/scopes/assign.tsx"; -import * as $admin_scopes_index from "./routes/admin/scopes/index.tsx"; -import * as $admin_users from "./routes/admin/users.tsx"; -import * as $auth from "./routes/auth.tsx"; -import * as $badges_package from "./routes/badges/package.ts"; -import * as $badges_package_score from "./routes/badges/package_score.ts"; -import * as $badges_scope from "./routes/badges/scope.ts"; -import * as $docs_id_ from "./routes/docs/[...id].tsx"; -import * as $docs_api_reference from "./routes/docs/api-reference.tsx"; -import * as $docs_index from "./routes/docs/index.ts"; -import * as $go_id_ from "./routes/go/[id].ts"; -import * as $index from "./routes/index.tsx"; -import * as $login from "./routes/login.tsx"; -import * as $logout from "./routes/logout.tsx"; -import * as $new from "./routes/new.tsx"; -import * as $package_all_symbols from "./routes/package/all_symbols.tsx"; -import * as $package_dependencies from "./routes/package/dependencies.tsx"; -import * as $package_dependents from "./routes/package/dependents.tsx"; -import * as $package_doc_file_ from "./routes/package/doc/[file].tsx"; -import * as $package_doc_symbol_ from "./routes/package/doc/[symbol].tsx"; -import * as $package_index from "./routes/package/index.tsx"; -import * as $package_og from "./routes/package/og.ts"; -import * as $package_publish from "./routes/package/publish.tsx"; -import * as $package_score from "./routes/package/score.tsx"; -import * as $package_settings from "./routes/package/settings.tsx"; -import * as $package_source from "./routes/package/source.tsx"; -import * as $package_versions from "./routes/package/versions.tsx"; -import * as $packages from "./routes/packages.tsx"; -import * as $publishing_deny from "./routes/publishing/deny.tsx"; -import * as $publishing_index from "./routes/publishing/index.tsx"; -import * as $status from "./routes/status.tsx"; -import * as $user_id_ from "./routes/user/[id].tsx"; -import * as $waitlist from "./routes/waitlist.tsx"; -import * as $Authorize from "./islands/Authorize.tsx"; -import * as $CopyButton from "./islands/CopyButton.tsx"; -import * as $DevelopmentLogin from "./islands/DevelopmentLogin.tsx"; -import * as $GitHubActionsLink from "./islands/GitHubActionsLink.tsx"; -import * as $GithubUserLink from "./islands/GithubUserLink.tsx"; -import * as $GlobalSearch from "./islands/GlobalSearch.tsx"; -import * as $HeaderLogo from "./islands/HeaderLogo.tsx"; -import * as $HomepageHeroParticles from "./islands/HomepageHeroParticles.tsx"; -import * as $PublishingTaskRequeue from "./islands/PublishingTaskRequeue.tsx"; -import * as $UserManageScopeInvite from "./islands/UserManageScopeInvite.tsx"; -import * as $UserMenu from "./islands/UserMenu.tsx"; -import * as $admin_ScopeEdit from "./islands/admin/ScopeEdit.tsx"; -import * as $admin_UserEdit from "./islands/admin/UserEdit.tsx"; -import * as $new_1 from "./islands/new.tsx"; -import * as $_scope_islands_ScopeInviteForm from "./routes/@[scope]/(_islands)/ScopeInviteForm.tsx"; -import * as $_scope_islands_ScopeMemberRole from "./routes/@[scope]/(_islands)/ScopeMemberRole.tsx"; -import * as $account_tokens_islands_CreateToken from "./routes/account/tokens/(_islands)/CreateToken.tsx"; -import * as $account_tokens_islands_RevokeToken from "./routes/account/tokens/(_islands)/RevokeToken.tsx"; -import * as $package_islands_BreadcrumbsSticky from "./routes/package/(_islands)/BreadcrumbsSticky.tsx"; -import * as $package_islands_LocalSymbolSearch from "./routes/package/(_islands)/LocalSymbolSearch.tsx"; -import * as $package_islands_PackageDescriptionEditor from "./routes/package/(_islands)/PackageDescriptionEditor.tsx"; -import * as $package_islands_PackageGitHubSettings from "./routes/package/(_islands)/PackageGitHubSettings.tsx"; -import * as $publishing_islands_OverallStatus from "./routes/publishing/(_islands)/OverallStatus.tsx"; -import * as $publishing_islands_publishing from "./routes/publishing/(_islands)/publishing.tsx"; -import type { Manifest } from "$fresh/server.ts"; - -const manifest = { - routes: { - "./routes/@[scope]/index.tsx": $_scope_index, - "./routes/@[scope]/~/index.tsx": $_scope_index_1, - "./routes/@[scope]/~/members.tsx": $_scope_members, - "./routes/@[scope]/~/settings.tsx": $_scope_settings, - "./routes/_404.tsx": $_404, - "./routes/_500.tsx": $_500, - "./routes/_app.tsx": $_app, - "./routes/_layout.tsx": $_layout, - "./routes/_middleware.ts": $_middleware, - "./routes/account/index.tsx": $account_index, - "./routes/account/invites.tsx": $account_invites, - "./routes/account/settings.tsx": $account_settings, - "./routes/account/tokens/create.tsx": $account_tokens_create, - "./routes/account/tokens/index.tsx": $account_tokens_index, - "./routes/admin/_middleware.ts": $admin_middleware, - "./routes/admin/index.tsx": $admin_index, - "./routes/admin/publishingTasks.tsx": $admin_publishingTasks, - "./routes/admin/scopes/assign.tsx": $admin_scopes_assign, - "./routes/admin/scopes/index.tsx": $admin_scopes_index, - "./routes/admin/users.tsx": $admin_users, - "./routes/auth.tsx": $auth, - "./routes/badges/package.ts": $badges_package, - "./routes/badges/package_score.ts": $badges_package_score, - "./routes/badges/scope.ts": $badges_scope, - "./routes/docs/[...id].tsx": $docs_id_, - "./routes/docs/api-reference.tsx": $docs_api_reference, - "./routes/docs/index.ts": $docs_index, - "./routes/go/[id].ts": $go_id_, - "./routes/index.tsx": $index, - "./routes/login.tsx": $login, - "./routes/logout.tsx": $logout, - "./routes/new.tsx": $new, - "./routes/package/all_symbols.tsx": $package_all_symbols, - "./routes/package/dependencies.tsx": $package_dependencies, - "./routes/package/dependents.tsx": $package_dependents, - "./routes/package/doc/[file].tsx": $package_doc_file_, - "./routes/package/doc/[symbol].tsx": $package_doc_symbol_, - "./routes/package/index.tsx": $package_index, - "./routes/package/og.ts": $package_og, - "./routes/package/publish.tsx": $package_publish, - "./routes/package/score.tsx": $package_score, - "./routes/package/settings.tsx": $package_settings, - "./routes/package/source.tsx": $package_source, - "./routes/package/versions.tsx": $package_versions, - "./routes/packages.tsx": $packages, - "./routes/publishing/deny.tsx": $publishing_deny, - "./routes/publishing/index.tsx": $publishing_index, - "./routes/status.tsx": $status, - "./routes/user/[id].tsx": $user_id_, - "./routes/waitlist.tsx": $waitlist, - }, - islands: { - "./islands/Authorize.tsx": $Authorize, - "./islands/CopyButton.tsx": $CopyButton, - "./islands/DevelopmentLogin.tsx": $DevelopmentLogin, - "./islands/GitHubActionsLink.tsx": $GitHubActionsLink, - "./islands/GithubUserLink.tsx": $GithubUserLink, - "./islands/GlobalSearch.tsx": $GlobalSearch, - "./islands/HeaderLogo.tsx": $HeaderLogo, - "./islands/HomepageHeroParticles.tsx": $HomepageHeroParticles, - "./islands/PublishingTaskRequeue.tsx": $PublishingTaskRequeue, - "./islands/UserManageScopeInvite.tsx": $UserManageScopeInvite, - "./islands/UserMenu.tsx": $UserMenu, - "./islands/admin/ScopeEdit.tsx": $admin_ScopeEdit, - "./islands/admin/UserEdit.tsx": $admin_UserEdit, - "./islands/new.tsx": $new_1, - "./routes/@[scope]/(_islands)/ScopeInviteForm.tsx": - $_scope_islands_ScopeInviteForm, - "./routes/@[scope]/(_islands)/ScopeMemberRole.tsx": - $_scope_islands_ScopeMemberRole, - "./routes/account/tokens/(_islands)/CreateToken.tsx": - $account_tokens_islands_CreateToken, - "./routes/account/tokens/(_islands)/RevokeToken.tsx": - $account_tokens_islands_RevokeToken, - "./routes/package/(_islands)/BreadcrumbsSticky.tsx": - $package_islands_BreadcrumbsSticky, - "./routes/package/(_islands)/LocalSymbolSearch.tsx": - $package_islands_LocalSymbolSearch, - "./routes/package/(_islands)/PackageDescriptionEditor.tsx": - $package_islands_PackageDescriptionEditor, - "./routes/package/(_islands)/PackageGitHubSettings.tsx": - $package_islands_PackageGitHubSettings, - "./routes/publishing/(_islands)/OverallStatus.tsx": - $publishing_islands_OverallStatus, - "./routes/publishing/(_islands)/publishing.tsx": - $publishing_islands_publishing, - }, - baseUrl: import.meta.url, -} satisfies Manifest; - -export default manifest; diff --git a/frontend/islands/GlobalSearch.tsx b/frontend/islands/GlobalSearch.tsx index 34e4fd3d..cc913ede 100644 --- a/frontend/islands/GlobalSearch.tsx +++ b/frontend/islands/GlobalSearch.tsx @@ -4,7 +4,7 @@ import { useEffect, useMemo, useRef } from "preact/hooks"; import { JSX } from "preact/jsx-runtime"; import { OramaClient } from "@oramacloud/client"; import { Highlight } from "@orama/highlight"; -import { IS_BROWSER } from "$fresh/runtime.ts"; +import { IS_BROWSER } from "fresh/runtime"; import type { OramaPackageHit, SearchKind } from "../util.ts"; import { api, path } from "../utils/api.ts"; import type { List, Package, RuntimeCompat } from "../utils/api_types.ts"; diff --git a/frontend/islands/admin/ScopeEdit.tsx b/frontend/islands/admin/ScopeEdit.tsx index 6bc0ada0..c4efd00c 100644 --- a/frontend/islands/admin/ScopeEdit.tsx +++ b/frontend/islands/admin/ScopeEdit.tsx @@ -1,7 +1,7 @@ // Copyright 2024 the JSR authors. All rights reserved. MIT license. import type { FullScope } from "../../utils/api_types.ts"; import { useState } from "preact/hooks"; -import twas from "$twas"; +import twas from "twas"; import { api, path } from "../../utils/api.ts"; import { TableData, TableRow } from "../../components/Table.tsx"; @@ -71,7 +71,7 @@ export default function AdminScopeEdit({ scope }: { scope: FullScope }) { : publishAttemptsPerWeekLimit} - {twas(new Date(scope.createdAt))} + {twas(new Date(scope.createdAt).getTime())} {edit diff --git a/frontend/islands/admin/UserEdit.tsx b/frontend/islands/admin/UserEdit.tsx index 94d50f9f..84268bd8 100644 --- a/frontend/islands/admin/UserEdit.tsx +++ b/frontend/islands/admin/UserEdit.tsx @@ -1,6 +1,6 @@ // Copyright 2024 the JSR authors. All rights reserved. MIT license. import { useState } from "preact/hooks"; -import twas from "$twas"; +import twas from "twas"; import { FullUser } from "../../utils/api_types.ts"; import { api, path } from "../../utils/api.ts"; import { TableData, TableRow } from "../../components/Table.tsx"; @@ -68,7 +68,7 @@ export default function UserEdit({ user }: { user: FullUser }) { : String(isBlocked)} - {twas(new Date(user.createdAt))} + {twas(new Date(user.createdAt).getTime())} {edit diff --git a/frontend/islands/new.tsx b/frontend/islands/new.tsx index 447b6d1d..64b1bfd7 100644 --- a/frontend/islands/new.tsx +++ b/frontend/islands/new.tsx @@ -8,7 +8,7 @@ import { import { Package, Scope } from "../utils/api_types.ts"; import { api, path } from "../utils/api.ts"; import { ComponentChildren } from "preact"; -import twas from "$twas"; +import twas from "twas"; interface IconColorProps { done: Signal; @@ -406,7 +406,7 @@ export function CreatePackage({ scope, name, pkg, fromCli }: {

{pkg.value.description || No description}

- Created {twas(new Date(pkg.value.createdAt))}. + Created {twas(new Date(pkg.value.createdAt).getTime())}.

{fromCli && (

diff --git a/frontend/main.ts b/frontend/main.ts index e6bb1299..3ab9b78a 100644 --- a/frontend/main.ts +++ b/frontend/main.ts @@ -1,12 +1,17 @@ // Copyright 2024 the JSR authors. All rights reserved. MIT license. -/// -/// -/// -/// -/// +import { App, fsRoutes, staticFiles, trailingSlashes } from "fresh"; +import { State } from "./util.ts"; -import { start } from "$fresh/server.ts"; -import manifest from "./fresh.gen.ts"; -import config from "./fresh.config.ts"; +export const app = new App() + .use(trailingSlashes("never")) + .use(staticFiles()); -await start(manifest, config); +await fsRoutes(app, { + dir: "./", + loadIsland: (path) => import(`./islands/${path}`), + loadRoute: (path) => import(`./routes/${path}`), +}); + +if (import.meta.main) { + await app.listen({ port: Number(Deno.env.get("PORT") ?? 8080) }); +} diff --git a/frontend/routes/@[scope]/(_islands)/ScopeMemberRole.tsx b/frontend/routes/@[scope]/(_islands)/ScopeMemberRole.tsx index 0043ba30..ead3cd83 100644 --- a/frontend/routes/@[scope]/(_islands)/ScopeMemberRole.tsx +++ b/frontend/routes/@[scope]/(_islands)/ScopeMemberRole.tsx @@ -2,7 +2,7 @@ import { useSignal } from "@preact/signals"; import { useCallback } from "preact/hooks"; import { api, path } from "../../../utils/api.ts"; -import { IS_BROWSER } from "$fresh/runtime.ts"; +import { IS_BROWSER } from "fresh/runtime"; export interface ScopeMemberRoleProps { scope: string; diff --git a/frontend/routes/@[scope]/index.tsx b/frontend/routes/@[scope]/index.tsx index 472cddb7..af85322e 100644 --- a/frontend/routes/@[scope]/index.tsx +++ b/frontend/routes/@[scope]/index.tsx @@ -1,47 +1,23 @@ // Copyright 2024 the JSR authors. All rights reserved. MIT license. -import { Handlers, PageProps } from "$fresh/server.ts"; -import { PaginationData, State } from "../../util.ts"; -import type { - FullScope, - List, - Package, - Scope, - ScopeInvite, - ScopeMember, -} from "../../utils/api_types.ts"; +import { HttpError } from "fresh"; +import { define } from "../../util.ts"; +import type { List, Package, ScopeInvite } from "../../utils/api_types.ts"; import { APIResponse, path } from "../../utils/api.ts"; import { ScopeNav } from "./(_components)/ScopeNav.tsx"; import { ScopeHeader } from "./(_components)/ScopeHeader.tsx"; import { scopeDataWithMember } from "../../utils/data.ts"; import { ScopePendingInvite } from "./(_components)/ScopePendingInvite.tsx"; -import { Head } from "$fresh/runtime.ts"; import { ListDisplay } from "../../components/List.tsx"; import { PackageHit } from "../../components/PackageHit.tsx"; import { scopeIAM } from "../../utils/iam.ts"; -interface Data extends PaginationData { - scope: Scope | FullScope; - scopeMember: ScopeMember | null; - packages: Package[]; - userInvites: ScopeInvite[] | null; -} - -export default function ScopePackagesPage( - { params, data, url, state }: PageProps, +export default define.page(function ScopePackagesPage( + { params, data, url, state }, ) { const iam = scopeIAM(state, data.scopeMember); return (

- - - @{params.scope} - JSR - - - @@ -53,10 +29,10 @@ export default function ScopePackagesPage(
); -} +}); -export const handler: Handlers = { - async GET(_req, ctx) { +export const handler = define.handlers({ + async GET(ctx) { const page = +(ctx.url.searchParams.get("page") || 1); // Default to large enough to display all of @std. const limit = +(ctx.url.searchParams.get("limit") || 50); @@ -71,24 +47,29 @@ export const handler: Handlers = { ? ctx.state.api.get(path`/user/invites`) : Promise.resolve(null), ]); - if (data === null) return ctx.renderNotFound(); + if (data === null) throw new HttpError(404, "The scope was not found."); if (!packagesResp.ok) { - if (packagesResp.code === "scopeNotFound") return ctx.renderNotFound(); + if (packagesResp.code === "scopeNotFound") { + throw new HttpError(404, "The scope was not found."); + } throw packagesResp; // graceful handle errors } if (userInvitesResp && !userInvitesResp.ok) throw userInvitesResp; - return ctx.render({ - scope: data.scope, - scopeMember: data.scopeMember, - packages: packagesResp.data.items, - userInvites: userInvitesResp?.data ?? null, - page, - limit, - total: packagesResp.data.total, - }); + return { + data: { + scope: data.scope, + scopeMember: data.scopeMember, + packages: packagesResp.data.items, + userInvites: userInvitesResp?.data ?? null, + page, + limit, + total: packagesResp.data.total, + }, + }; }, - async POST(req, ctx) { + async POST(ctx) { + const req = ctx.req; const scope = ctx.params.scope; const form = await req.formData(); const action = form.get("action"); @@ -101,9 +82,10 @@ export const handler: Handlers = { throw new Error("invalid action"); } if (!res.ok) throw res; // graceful handle errors - return new Response(null, { - status: 303, - headers: { location: `/@${scope}` }, - }); + ctx.state.meta = { + title: `@${scope} - JSR`, + description: `@${scope} on JSR`, + }; + return ctx.redirect(`/@${scope}`, 303); }, -}; +}); diff --git a/frontend/routes/@[scope]/~/index.tsx b/frontend/routes/@[scope]/~/index.tsx index dbf0fe6a..6d9f948e 100644 --- a/frontend/routes/@[scope]/~/index.tsx +++ b/frontend/routes/@[scope]/~/index.tsx @@ -1,9 +1,8 @@ // Copyright 2024 the JSR authors. All rights reserved. MIT license. -import { Handlers } from "$fresh/server.ts"; -import { State } from "../../../util.ts"; +import { define } from "../../../util.ts"; -export const handler: Handlers = { - GET(_req, ctx) { +export const handler = define.handlers({ + GET(ctx) { return new Response("", { status: 302, headers: { @@ -11,4 +10,4 @@ export const handler: Handlers = { }, }); }, -}; +}); diff --git a/frontend/routes/@[scope]/~/members.tsx b/frontend/routes/@[scope]/~/members.tsx index 2d15bda1..4490fea7 100644 --- a/frontend/routes/@[scope]/~/members.tsx +++ b/frontend/routes/@[scope]/~/members.tsx @@ -1,6 +1,6 @@ // Copyright 2024 the JSR authors. All rights reserved. MIT license. -import { Handlers, PageProps } from "$fresh/server.ts"; -import { Head } from "$fresh/runtime.ts"; +import { HttpError } from "fresh"; +import { define } from "../../../util.ts"; import { ScopeHeader } from "../(_components)/ScopeHeader.tsx"; import { ScopeNav } from "../(_components)/ScopeNav.tsx"; import { ScopePendingInvite } from "../(_components)/ScopePendingInvite.tsx"; @@ -8,12 +8,9 @@ import { ScopeInviteForm } from "../(_islands)/ScopeInviteForm.tsx"; import { ScopeMemberRole } from "../(_islands)/ScopeMemberRole.tsx"; import { Table, TableData, TableRow } from "../../../components/Table.tsx"; import { CopyButton } from "../../../islands/CopyButton.tsx"; -import { State } from "../../../util.ts"; import { path } from "../../../utils/api.ts"; import { - FullScope, FullUser, - Scope, ScopeInvite, ScopeMember, } from "../../../utils/api_types.ts"; @@ -22,20 +19,14 @@ import { TrashCan } from "../../../components/icons/TrashCan.tsx"; import { scopeIAM } from "../../../utils/iam.ts"; import { ScopeIAM } from "../../../utils/iam.ts"; -interface Data { - scope: Scope | FullScope; - scopeMember: ScopeMember | null; - members: ScopeMember[]; - invites: ScopeInvite[]; -} - -export default function ScopeMembersPage( - { params, data, state, url }: PageProps, +export default define.page(function ScopeMembersPage( + { params, data, state, url }, ) { const iam = scopeIAM(state, data.scopeMember); - const hasOneAdmin = - data.members.filter((member) => member.isAdmin).length === 1; + const hasOneAdmin = data.members.filter((member) => + member.isAdmin + ).length === 1; const isLastAdmin = (data.scopeMember?.isAdmin || false) && hasOneAdmin; @@ -43,11 +34,6 @@ export default function ScopeMembersPage( return (
- - - Members - @{params.scope} - JSR - - ); -} +}); interface MemberItemProps { isLastAdmin: boolean; @@ -244,8 +230,8 @@ function MemberLeave( ); } -export const handler: Handlers = { - async GET(_req, ctx) { +export const handler = define.handlers({ + async GET(ctx) { let [user, data, membersResp, invitesResp] = await Promise.all([ ctx.state.userPromise, scopeData(ctx.state, ctx.params.scope), @@ -259,9 +245,11 @@ export const handler: Handlers = { : Promise.resolve(null), ]); if (user instanceof Response) return user; - if (data === null) return ctx.renderNotFound(); + if (data === null) throw new HttpError(404, "The scope was not found."); if (!membersResp.ok) { - if (membersResp.code === "scopeNotFound") return ctx.renderNotFound(); + if (membersResp.code === "scopeNotFound") { + throw new HttpError(404, "The scope was not found."); + } throw membersResp; // graceful handle errors } if (invitesResp && !invitesResp.ok) { @@ -271,24 +259,32 @@ export const handler: Handlers = { ) { invitesResp = null; } else { - if (invitesResp.code === "scopeNotFound") return ctx.renderNotFound(); + if (invitesResp.code === "scopeNotFound") { + throw new HttpError(404, "The scope was not found."); + } throw invitesResp; // graceful handle errors } } - const scopeMember = - membersResp.data.find((member) => - member.user.id === (user as FullUser | null)?.id - ) ?? null; + const scopeMember = membersResp.data.find((member) => + member.user.id === (user as FullUser | null)?.id + ) ?? null; - return ctx.render({ - scope: data.scope, - scopeMember: scopeMember, - members: membersResp.data, - invites: invitesResp?.data ?? [], - }); + ctx.state.meta = { + title: `Members - @${ctx.params.scope} - JSR`, + description: `List of members of the @${ctx.params.scope} scope on JSR.`, + }; + return { + data: { + scope: data.scope, + scopeMember: scopeMember, + members: membersResp.data, + invites: invitesResp?.data ?? [], + }, + }; }, - async POST(req, ctx) { + async POST(ctx) { + const req = ctx.req; const scope = ctx.params.scope; const form = await req.formData(); const action = form.get("action"); @@ -298,7 +294,9 @@ export const handler: Handlers = { path`/scopes/${scope}/invites/${userId}`, ); if (!res.ok) { - if (res.code === "scopeNotFound") return ctx.renderNotFound(); + if (res.code === "scopeNotFound") { + throw new HttpError(404, "The scope was not found."); + } throw res; // graceful handle errors } } else if (action === "deleteMember") { @@ -307,7 +305,9 @@ export const handler: Handlers = { path`/scopes/${scope}/members/${userId}`, ); if (!res.ok) { - if (res.code === "scopeNotFound") return ctx.renderNotFound(); + if (res.code === "scopeNotFound") { + throw new HttpError(404, "The scope was not found."); + } throw res; // graceful handle errors } } else if (action === "invite") { @@ -317,7 +317,9 @@ export const handler: Handlers = { { githubLogin }, ); if (!res.ok) { - if (res.code === "scopeNotFound") return ctx.renderNotFound(); + if (res.code === "scopeNotFound") { + throw new HttpError(404, "The scope was not found."); + } throw res; // graceful handle errors } } else { @@ -328,4 +330,4 @@ export const handler: Handlers = { headers: { Location: `/@${scope}/~/members` }, }); }, -}; +}); diff --git a/frontend/routes/@[scope]/~/settings.tsx b/frontend/routes/@[scope]/~/settings.tsx index a416567f..20997b11 100644 --- a/frontend/routes/@[scope]/~/settings.tsx +++ b/frontend/routes/@[scope]/~/settings.tsx @@ -1,32 +1,21 @@ // Copyright 2024 the JSR authors. All rights reserved. MIT license. -import { Handlers, PageProps } from "$fresh/server.ts"; +import { HttpError } from "fresh"; import { ComponentChildren } from "preact"; +import { define } from "../../../util.ts"; import { ScopeHeader } from "../(_components)/ScopeHeader.tsx"; import { ScopeNav } from "../(_components)/ScopeNav.tsx"; -import { State } from "../../../util.ts"; import { FullScope, User } from "../../../utils/api_types.ts"; import { scopeDataWithMember } from "../../../utils/data.ts"; import { path } from "../../../utils/api.ts"; import { QuotaCard } from "../../../components/QuotaCard.tsx"; -import { Head } from "$fresh/runtime.ts"; import { Check } from "../../../components/icons/Check.tsx"; -import { ScopeIAM, scopeIAM } from "../../../utils/iam.ts"; +import { scopeIAM } from "../../../utils/iam.ts"; -interface Data { - scope: FullScope; - iam: ScopeIAM; -} - -export default function ScopeSettingsPage( - { params, data, state }: PageProps, +export default define.page(function ScopeSettingsPage( + { data, state }, ) { return (
- - - Settings - @{params.scope} - JSR - - @@ -35,7 +24,7 @@ export default function ScopeSettingsPage(
); -} +}); function ScopeQuotas({ scope, user }: { scope: FullScope; user: User }) { const requestLimitIncreaseBody = `Hello JSR team, @@ -261,24 +250,28 @@ function DeleteScope({ scope }: { scope: FullScope }) { ); } -export const handler: Handlers = { - async GET(_req, ctx) { +export const handler = define.handlers({ + async GET(ctx) { const [user, data] = await Promise.all([ ctx.state.userPromise, scopeDataWithMember(ctx.state, ctx.params.scope), ]); if (user instanceof Response) return user; - if (data === null) return ctx.renderNotFound(); + if (data === null) throw new HttpError(404, "The scope was not found."); const iam = scopeIAM(ctx.state, data?.scopeMember, user); - if (!iam.canAdmin) return ctx.renderNotFound(); + if (!iam.canAdmin) throw new HttpError(404, "The scope was not found."); - return ctx.render({ - scope: data.scope as FullScope, - iam, - }); + ctx.state.meta = { title: `Settings - @${data.scope.scope} - JSR` }; + return { + data: { + scope: data.scope as FullScope, + iam, + }, + }; }, - async POST(req, ctx) { + async POST(ctx) { + const req = ctx.req; const scope = ctx.params.scope; const form = await req.formData(); const action = String(form.get("action")); @@ -293,7 +286,9 @@ export const handler: Handlers = { { ghActionsVerifyActor: enableGhActionsVerifyActor }, ); if (!res.ok) { - if (res.code === "scopeNotFound") return ctx.renderNotFound(); + if (res.code === "scopeNotFound") { + throw new HttpError(404, "The scope was not found."); + } throw res; // graceful handle errors } return new Response(null, { @@ -308,7 +303,9 @@ export const handler: Handlers = { { requirePublishingFromCI: value }, ); if (!res.ok) { - if (res.code === "scopeNotFound") return ctx.renderNotFound(); + if (res.code === "scopeNotFound") { + throw new HttpError(404, "The scope was not found."); + } throw res; // graceful handle errors } return new Response(null, { @@ -319,7 +316,9 @@ export const handler: Handlers = { case "deleteScope": { const res = await ctx.state.api.delete(path`/scopes/${scope}`); if (!res.ok) { - if (res.code === "scopeNotFound") return ctx.renderNotFound(); + if (res.code === "scopeNotFound") { + throw new HttpError(404, "The scope was not found."); + } throw res; // graceful handle errors } return new Response(null, { @@ -331,4 +330,4 @@ export const handler: Handlers = { throw new Error("Invalid action " + action); } }, -}; +}); diff --git a/frontend/routes/_404.tsx b/frontend/routes/_404.tsx deleted file mode 100644 index 0f30a0c2..00000000 --- a/frontend/routes/_404.tsx +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2024 the JSR authors. All rights reserved. MIT license. -import { Head } from "$fresh/runtime.ts"; - -export default function NotFoundPage() { - return ( - <> - - - -
-
-
-

- 404 -

-

- Couldn't find what you're looking for. -

-
-
-
- - ); -} diff --git a/frontend/routes/_500.tsx b/frontend/routes/_500.tsx deleted file mode 100644 index 018a77dd..00000000 --- a/frontend/routes/_500.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { APIResponseError } from "../utils/api.ts"; -import { ErrorDisplay } from "../components/ErrorDisplay.tsx"; - -// Copyright 2024 the JSR authors. All rights reserved. MIT license. -export default function Error({ error }: { error: unknown }) { - if ( - typeof error === "object" && error !== null && "ok" in error && - error.ok === false && "status" in error && "code" in error && - "message" in error && - "traceId" in error - ) { - return ; - } - - return ( -
-

Error

-
{JSON.stringify(error, null, 2)}
-
- ); -} diff --git a/frontend/routes/_app.tsx b/frontend/routes/_app.tsx index 164313d5..a62ec106 100644 --- a/frontend/routes/_app.tsx +++ b/frontend/routes/_app.tsx @@ -1,12 +1,15 @@ // Copyright 2024 the JSR authors. All rights reserved. MIT license. -import { PageProps } from "$fresh/server.ts"; -import { asset } from "$fresh/runtime.ts"; +import { PageProps } from "fresh"; +import { asset } from "fresh/runtime"; import { State } from "../util.ts"; -export default async function App( - _req: Request, - { Component, state }: PageProps, -) { +const FRONTEND_ROOT = Deno.env.get("FRONTEND_ROOT") ?? "http://jsr.test"; + +export default async function App({ + Component, + state, + url, +}: PageProps) { const user = await state.userPromise; if (user instanceof Response) return user; Object.defineProperty(state, "user", { value: user }); @@ -15,9 +18,35 @@ export default async function App( + {state.meta?.title && ( + <> + {state.meta.title} + + + )} + {state.meta?.description && ( + <> + + + + )} + + + + + + + +