From f7e4eb83694aa007a492ef66c28ffbe6a2dae791 Mon Sep 17 00:00:00 2001 From: Ashcon Partovi Date: Tue, 7 Mar 2023 12:22:34 -0800 Subject: Reorganize tests (#2332) --- test/bun.js/websocket-server.test.ts | 963 ----------------------------------- 1 file changed, 963 deletions(-) delete mode 100644 test/bun.js/websocket-server.test.ts (limited to 'test/bun.js/websocket-server.test.ts') diff --git a/test/bun.js/websocket-server.test.ts b/test/bun.js/websocket-server.test.ts deleted file mode 100644 index 3205ff949..000000000 --- a/test/bun.js/websocket-server.test.ts +++ /dev/null @@ -1,963 +0,0 @@ -import { describe, expect, it } from "bun:test"; -import { gcTick } from "./gc"; -import { serve } from "bun"; - -var port = 4301; -function getPort() { - if (port > 4444) { - port = 4321; - } - - return port++; -} - -describe("websocket server", () => { - it("can do publish()", async done => { - var server = serve({ - port: getPort(), - websocket: { - open(ws) { - ws.subscribe("all"); - }, - message(ws, msg) {}, - close(ws) {}, - }, - fetch(req, server) { - if (server.upgrade(req)) { - return; - } - - return new Response("success"); - }, - }); - - await new Promise((resolve2, reject2) => { - var socket = new WebSocket(`ws://${server.hostname}:${server.port}`); - var clientCounter = 0; - - socket.onmessage = e => { - expect(e.data).toBe("hello"); - resolve2(); - }; - socket.onopen = () => { - queueMicrotask(() => { - server.publish("all", "hello"); - }); - }; - }); - server.stop(true); - done(); - }); - - it("can do publish() with publishToSelf: false", async done => { - var server = serve({ - port: getPort(), - websocket: { - open(ws) { - ws.subscribe("all"); - ws.publish("all", "hey"); - server.publish("all", "hello"); - }, - message(ws, msg) { - if (new TextDecoder().decode(msg) !== "hello") { - done(new Error("unexpected message")); - } - }, - close(ws) {}, - publishToSelf: false, - }, - fetch(req, server) { - if (server.upgrade(req)) { - return; - } - - return new Response("success"); - }, - }); - - await new Promise((resolve2, reject2) => { - var socket = new WebSocket(`ws://${server.hostname}:${server.port}`); - - socket.onmessage = e => { - expect(e.data).toBe("hello"); - resolve2(); - }; - }); - server.stop(true); - done(); - }); - - for (let method of ["publish", "publishText", "publishBinary"]) { - describe(method, () => { - it("in close() should work", async () => { - var count = 0; - var server = serve({ - port: getPort(), - websocket: { - open(ws) { - ws.subscribe("all"); - }, - message(ws, msg) {}, - close(ws) { - ws[method]("all", method === "publishBinary" ? Buffer.from("bye!") : "bye!"); - count++; - - if (count >= 2) { - server.stop(true); - } - }, - }, - fetch(req, server) { - if (server.upgrade(req)) { - return; - } - - return new Response("success"); - }, - }); - - try { - const first = await new Promise((resolve2, reject2) => { - var socket = new WebSocket(`ws://${server.hostname}:${server.port}`); - socket.onopen = () => resolve2(socket); - }); - - await new Promise((resolve2, reject2) => { - var socket = new WebSocket(`ws://${server.hostname}:${server.port}`); - socket.onopen = () => { - queueMicrotask(() => first.close()); - }; - socket.onmessage = ev => { - var msg = ev.data; - if (typeof msg !== "string") { - msg = new TextDecoder().decode(msg); - } - - if (msg === "bye!") { - socket.close(0); - resolve2(socket); - } else { - reject2(msg); - } - }; - }); - } finally { - server.stop(true); - } - }); - }); - } - - it("close inside open", async () => { - var resolve; - console.trace("here"); - var server = serve({ - port: getPort(), - websocket: { - open(ws) {}, - message(ws, msg) {}, - close() { - resolve(); - server.stop(true); - }, - }, - fetch(req, server) { - if ( - server.upgrade(req, { - data: "hello world", - - // check that headers works - headers: { - "x-a": "text/plain", - }, - }) - ) { - if (server.upgrade(req)) { - throw new Error("should not upgrade twice"); - } - return; - } - - return new Response("noooooo hello world"); - }, - }); - - await new Promise((resolve_, reject) => { - resolve = resolve_; - const websocket = new WebSocket(`ws://${server.hostname}:${server.port}`); - websocket.onopen = () => { - websocket.close(); - }; - websocket.onmessage = e => {}; - websocket.onerror = e => {}; - }); - }); - - it("headers error doesn't crash", async () => { - await new Promise((resolve, reject) => { - const server = serve({ - port: getPort(), - websocket: { - open(ws) { - ws.close(); - }, - message(ws, msg) {}, - close() { - resolve(); - server.stop(true); - }, - }, - error(err) { - resolve(); - server.stop(true); - }, - fetch(req, server) { - expect(() => { - if ( - server.upgrade(req, { - data: "hello world", - headers: 1238 as any, - }) - ) { - reject(new Error("should not upgrade")); - return new Response("should not upgrade"); - } - }).toThrow("upgrade options.headers must be a Headers or an object"); - resolve(); - return new Response("success"); - }, - }); - - const websocket = new WebSocket(`ws://${server.hostname}:${server.port}`); - websocket.onopen = () => websocket.close(); - websocket.onmessage = e => {}; - websocket.onerror = e => {}; - }); - }); - it("can do hello world", async () => { - const server = serve({ - port: getPort(), - websocket: { - open(ws) { - server.stop(); - }, - message(ws, msg) { - ws.send("hello world"); - }, - }, - fetch(req, server) { - server.stop(); - if ( - server.upgrade(req, { - data: "hello world", - - // check that headers works - headers: { - "x-a": "text/plain", - }, - }) - ) { - if (server.upgrade(req)) { - throw new Error("should not upgrade twice"); - } - return; - } - - return new Response("noooooo hello world"); - }, - }); - - await new Promise((resolve, reject) => { - const websocket = new WebSocket(`ws://${server.hostname}:${server.port}`); - websocket.onopen = () => { - websocket.send("hello world"); - }; - websocket.onmessage = e => { - try { - expect(e.data).toBe("hello world"); - resolve(); - } catch (r) { - reject(r); - } finally { - websocket.close(); - } - }; - websocket.onerror = e => { - reject(e); - }; - }); - }); - - it("fetch() allows a Response object to be returned for an upgraded ServerWebSocket", () => { - const server = serve({ - port: getPort(), - websocket: { - open(ws) { - server.stop(); - }, - message(ws, msg) { - ws.send("hello world"); - }, - }, - error(err) { - console.error(err); - }, - fetch(req, server) { - server.stop(); - if ( - server.upgrade(req, { - data: "hello world", - - // check that headers works - headers: { - "x-a": "text/plain", - }, - }) - ) { - if (server.upgrade(req)) { - throw new Error("should not upgrade twice"); - } - return new Response("lol!", { - status: 101, - }); - } - - return new Response("noooooo hello world"); - }, - }); - - return new Promise((resolve, reject) => { - const websocket = new WebSocket(`ws://${server.hostname}:${server.port}`); - websocket.onopen = () => { - websocket.send("hello world"); - }; - websocket.onmessage = e => { - try { - expect(e.data).toBe("hello world"); - resolve(); - } catch (r) { - reject(r); - } finally { - websocket.close(); - } - }; - websocket.onerror = e => { - reject(e); - }; - }); - }); - - it("fetch() allows a Promise object to be returned for an upgraded ServerWebSocket", () => { - const server = serve({ - port: getPort(), - websocket: { - async open(ws) { - server.stop(); - }, - async message(ws, msg) { - await 1; - ws.send("hello world"); - }, - }, - error(err) { - console.error(err); - }, - async fetch(req, server) { - server.stop(); - await 1; - if ( - server.upgrade(req, { - data: "hello world", - - // check that headers works - headers: { - "x-a": "text/plain", - }, - }) - ) { - if (server.upgrade(req)) { - throw new Error("should not upgrade twice"); - } - return new Response("lol!", { - status: 101, - }); - } - - return new Response("noooooo hello world"); - }, - }); - return new Promise((resolve, reject) => { - const websocket = new WebSocket(`ws://${server.hostname}:${server.port}`); - websocket.onopen = () => { - websocket.send("hello world"); - }; - websocket.onmessage = e => { - try { - expect(e.data).toBe("hello world"); - resolve(); - } catch (r) { - reject(r); - } finally { - websocket.close(); - } - }; - websocket.onerror = e => { - reject(e); - }; - }); - }); - it("binaryType works", async () => { - var done = false; - const server = serve({ - port: getPort(), - websocket: { - open(ws) { - server.stop(); - }, - message(ws, msg) { - if (ws.binaryType === "uint8array") { - expect(ws.binaryType).toBe("uint8array"); - ws.binaryType = "arraybuffer"; - expect(ws.binaryType).toBe("arraybuffer"); - expect(msg instanceof Uint8Array).toBe(true); - } else { - expect(ws.binaryType).toBe("arraybuffer"); - expect(msg instanceof ArrayBuffer).toBe(true); - done = true; - } - - ws.send("hello world"); - }, - }, - fetch(req, server) { - server.stop(); - if (server.upgrade(req, { data: "hello world" })) { - if (server.upgrade(req)) { - throw new Error("should not upgrade twice"); - } - return; - } - - return new Response("noooooo hello world"); - }, - }); - - await new Promise((resolve, reject) => { - var counter = 0; - const websocket = new WebSocket(`ws://${server.hostname}:${server.port}`); - websocket.onopen = () => { - websocket.send(Buffer.from("hello world")); - }; - websocket.onmessage = e => { - try { - expect(e.data).toBe("hello world"); - - if (counter++ > 0) { - websocket.close(); - resolve(done); - } - websocket.send(Buffer.from("oaksd")); - } catch (r) { - websocket.close(); - reject(r); - } - }; - websocket.onerror = e => { - reject(e); - }; - }); - }); - - it("does not upgrade for non-websocket connections", async () => { - await new Promise(async (resolve, reject) => { - var server = serve({ - port: getPort(), - websocket: { - open(ws) { - ws.send("hello world"); - }, - message(ws, msg) {}, - }, - fetch(req, server) { - if (server.upgrade(req)) { - reject(new Error("should not upgrade")); - } - - return new Response("success"); - }, - }); - - const response = await fetch(`http://${server.hostname}:${server.port}`); - expect(await response.text()).toBe("success"); - resolve(); - server.stop(true); - }); - }); - - it("does not upgrade for non-websocket servers", async () => { - await new Promise(async (resolve, reject) => { - const server = serve({ - port: getPort(), - fetch(req, server) { - server.stop(); - expect(() => { - server.upgrade(req); - }).toThrow('To enable websocket support, set the "websocket" object in Bun.serve({})'); - return new Response("success"); - }, - }); - - const response = await fetch(`http://${server.hostname}:${server.port}`); - expect(await response.text()).toBe("success"); - resolve(); - }); - }); - - it("async can do hello world", async () => { - const server = serve({ - port: getPort(), - websocket: { - async open(ws) { - server.stop(true); - ws.send("hello world"); - }, - message(ws, msg) {}, - }, - async fetch(req, server) { - server.stop(); - await 1; - if (server.upgrade(req)) return; - - return new Response("noooooo hello world"); - }, - }); - - await new Promise((resolve, reject) => { - const websocket = new WebSocket(`ws://${server.hostname}:${server.port}`); - - websocket.onmessage = e => { - try { - expect(e.data).toBe("hello world"); - resolve(); - } catch (r) { - reject(r); - } finally { - websocket.close(); - } - }; - websocket.onerror = e => { - reject(e); - }; - }); - }); - - it("publishText()", async () => { - await new Promise((resolve, reject) => { - var websocket; - var server = serve({ - port: getPort(), - websocket: { - async open(ws) { - // we don't care about the data - // we just want to make sure the DOMJIT call doesn't crash - for (let i = 0; i < 40_000; i++) ws.publishText("hello", "world"); - websocket.close(); - server.stop(true); - resolve(); - }, - message(ws, msg) {}, - }, - async fetch(req, server) { - await 1; - if (server.upgrade(req)) return; - - return new Response("noooooo hello world"); - }, - }); - - websocket = new WebSocket(`ws://${server.hostname}:${server.port}`); - }); - }); - - it("publishBinary()", async () => { - const bytes = Buffer.from("hello"); - - await new Promise((resolve, reject) => { - var websocket; - var server = serve({ - port: getPort(), - websocket: { - async open(ws) { - // we don't care about the data - // we just want to make sure the DOMJIT call doesn't crash - for (let i = 0; i < 40_000; i++) ws.publishBinary("hello", bytes); - websocket.close(); - server.stop(true); - resolve(); - }, - message(ws, msg) {}, - }, - async fetch(req, server) { - await 1; - if (server.upgrade(req)) return; - - return new Response("noooooo hello world"); - }, - }); - - websocket = new WebSocket(`ws://${server.hostname}:${server.port}`); - }); - }); - - it("sendText()", async () => { - await new Promise((resolve, reject) => { - var websocket; - var server = serve({ - port: getPort(), - websocket: { - async open(ws) { - // we don't care about the data - // we just want to make sure the DOMJIT call doesn't crash - for (let i = 0; i < 40_000; i++) ws.sendText("hello world", true); - resolve(); - websocket.close(); - server.stop(true); - }, - message(ws, msg) {}, - }, - async fetch(req, server) { - await 1; - if (server.upgrade(req)) return; - - return new Response("noooooo hello world"); - }, - }); - websocket = new WebSocket(`ws://${server.hostname}:${server.port}`); - }); - }); - - it("sendBinary()", async () => { - const bytes = Buffer.from("hello"); - await new Promise((resolve, reject) => { - var websocket; - var server = serve({ - port: getPort(), - websocket: { - async open(ws) { - // we don't care about the data - // we just want to make sure the DOMJIT call doesn't crash - for (let i = 0; i < 40_000; i++) ws.sendBinary(bytes, true); - websocket.close(); - server.stop(true); - resolve(); - }, - message(ws, msg) {}, - }, - async fetch(req, server) { - await 1; - if (server.upgrade(req)) return; - - return new Response("noooooo hello world"); - }, - }); - - websocket = new WebSocket(`ws://${server.hostname}:${server.port}`); - }); - }); - - it("can do hello world corked", async () => { - const server = serve({ - port: getPort(), - websocket: { - open(ws) { - server.stop(); - ws.send("hello world"); - }, - message(ws, msg) { - ws.cork(() => { - ws.send("hello world"); - }); - }, - }, - fetch(req, server) { - server.stop(); - if (server.upgrade(req)) return; - return new Response("noooooo hello world"); - }, - }); - - await new Promise((resolve, reject) => { - const websocket = new WebSocket(`ws://${server.hostname}:${server.port}`); - - websocket.onmessage = e => { - try { - expect(e.data).toBe("hello world"); - resolve(); - } catch (r) { - reject(r); - } finally { - websocket.close(); - } - }; - websocket.onerror = e => { - reject(e); - }; - }); - server.stop(true); - }); - - it("can do some back and forth", async () => { - var dataCount = 0; - const server = serve({ - port: getPort(), - websocket: { - open(ws) { - server.stop(); - }, - message(ws, msg) { - if (msg === "first") { - ws.send("first"); - return; - } - ws.send(`counter: ${dataCount++}`); - }, - }, - fetch(req, server) { - server.stop(); - if ( - server.upgrade(req, { - data: { count: 0 }, - }) - ) - return new Response("noooooo hello world"); - }, - }); - - await new Promise((resolve, reject) => { - const websocket = new WebSocket(`ws://${server.hostname}:${server.port}`); - websocket.onerror = e => { - reject(e); - }; - - var counter = 0; - websocket.onopen = () => websocket.send("first"); - websocket.onmessage = e => { - try { - switch (counter++) { - case 0: { - expect(e.data).toBe("first"); - websocket.send("where are the loops"); - break; - } - case 1: { - expect(e.data).toBe("counter: 0"); - websocket.send("br0ther may i have some loops"); - break; - } - case 2: { - expect(e.data).toBe("counter: 1"); - websocket.send("br0ther may i have some loops"); - break; - } - case 3: { - expect(e.data).toBe("counter: 2"); - resolve(); - break; - } - } - } catch (r) { - reject(r); - websocket.close(); - } - }; - }); - server.stop(true); - }); - - it("send rope strings", async () => { - var ropey = "hello world".repeat(10); - var sendQueue: any[] = []; - for (var i = 0; i < 100; i++) { - sendQueue.push(ropey + " " + i); - } - - var serverCounter = 0; - var clientCounter = 0; - - const server = serve({ - port: getPort(), - websocket: { - open(ws) { - server.stop(); - }, - message(ws, msg) { - ws.send(sendQueue[serverCounter++] + " "); - gcTick(); - }, - }, - fetch(req, server) { - server.stop(); - if ( - server.upgrade(req, { - data: { count: 0 }, - }) - ) - return; - - return new Response("noooooo hello world"); - }, - }); - - await new Promise((resolve, reject) => { - const websocket = new WebSocket(`ws://${server.hostname}:${server.port}`); - websocket.onerror = e => { - reject(e); - }; - - var counter = 0; - websocket.onopen = () => websocket.send("first"); - websocket.onmessage = e => { - try { - const expected = sendQueue[clientCounter++] + " "; - expect(e.data).toBe(expected); - websocket.send("next"); - if (clientCounter === sendQueue.length) { - websocket.close(); - resolve(); - } - } catch (r) { - reject(r); - console.error(r); - websocket.close(); - } - }; - }); - server.stop(true); - }); - - // this test sends 100 messages to 10 connected clients via pubsub - it("pub/sub", async () => { - var ropey = "hello world".repeat(10); - var sendQueue: any[] = []; - for (var i = 0; i < 100; i++) { - sendQueue.push(ropey + " " + i); - gcTick(); - } - var serverCounter = 0; - var clientCount = 0; - const server = serve({ - port: getPort(), - websocket: { - open(ws) { - server.stop(); - ws.subscribe("test"); - gcTick(); - if (!ws.isSubscribed("test")) { - throw new Error("not subscribed"); - } - ws.unsubscribe("test"); - if (ws.isSubscribed("test")) { - throw new Error("subscribed"); - } - ws.subscribe("test"); - clientCount++; - if (clientCount === 10) setTimeout(() => ws.publish("test", "hello world"), 1); - }, - message(ws, msg) { - if (serverCounter < sendQueue.length) ws.publish("test", sendQueue[serverCounter++] + " "); - }, - }, - fetch(req) { - gcTick(); - server.stop(); - if ( - server.upgrade(req, { - data: { count: 0 }, - }) - ) - return; - return new Response("noooooo hello world"); - }, - }); - - const connections = new Array(10); - const websockets = new Array(connections.length); - var doneCounter = 0; - await new Promise(done => { - for (var i = 0; i < connections.length; i++) { - var j = i; - var resolve, reject, resolveConnection, rejectConnection; - connections[j] = new Promise((res, rej) => { - resolveConnection = res; - rejectConnection = rej; - }); - websockets[j] = new Promise((res, rej) => { - resolve = res; - reject = rej; - }); - gcTick(); - const websocket = new WebSocket(`ws://${server.hostname}:${server.port}`); - websocket.onerror = e => { - reject(e); - }; - websocket.onclose = () => { - doneCounter++; - if (doneCounter === connections.length) { - done(); - } - }; - var hasOpened = false; - websocket.onopen = () => { - if (!hasOpened) { - hasOpened = true; - resolve(websocket); - } - }; - - let clientCounter = -1; - var hasSentThisTick = false; - - websocket.onmessage = e => { - gcTick(); - - if (!hasOpened) { - hasOpened = true; - resolve(websocket); - } - - if (e.data === "hello world") { - clientCounter = 0; - websocket.send("first"); - return; - } - - try { - expect(!!sendQueue.find(a => a + " " === e.data)).toBe(true); - - if (!hasSentThisTick) { - websocket.send("second"); - hasSentThisTick = true; - queueMicrotask(() => { - hasSentThisTick = false; - }); - } - - gcTick(); - - if (clientCounter++ === sendQueue.length - 1) { - websocket.close(); - resolveConnection(); - } - } catch (r) { - console.error(r); - websocket.close(); - rejectConnection(r); - gcTick(); - } - }; - } - }); - expect(serverCounter).toBe(sendQueue.length); - server.stop(true); - }); -}); -- cgit v1.2.3 d=b21dd19cb6773282aaa0eac6e5e61b92bcb85836&follow=1'>chore: remove www (#2361)Gravatar Nate Moore 87-3240/+11 2022-01-11Fix build output in static build mode (#2358)Gravatar Matthew Phillips 3-1/+16 * Fix build output in static build mode * Adds a changeset * Formatting 2022-01-11Fix renderer-solid (fix #2336) (#2359)Gravatar toSayNothing 2-1/+6 2022-01-11[ci] collect statsGravatar FredKSchott 1-0/+1 2022-01-10Use smooth scrolling with reduced motion has no preference (#2355)Gravatar Jonathan Neal 1-3/+7 2022-01-10move changeset to run after build, no test required (#2341)Gravatar Fred K. Schott 1-2/+2 2022-01-10Note that Astro also supports `<Fragment>` syntax (#2354)Gravatar Zade Viggers 1-16/+18 2022-01-10smooth scroll behavior property added (#2256)Gravatar Divyamrit 1-1/+3 * smooth scroll behavior property added * [ci] yarn format Co-authored-by: sacarvy <sacarvy@users.noreply.github.com> 2022-01-10Add Astro Blog RSS feed (#2301)Gravatar Rafael Bardini 2-3/+20 * Generate RSS feed * Add RSS feed link 2022-01-10Update Cloudflare Pages guide (#2345)Gravatar Jacob Rask 1-2/+2 See https://developers.cloudflare.com/pages/framework-guides/astro 2022-01-10[ci] update lockfile (#2351)Gravatar Fred K. Schott 1-116/+116 Co-authored-by: FredKSchott <FredKSchott@users.noreply.github.com> 2022-01-10Update instructions for the monorepo (#2274)Gravatar Caleb Jasik 1-5/+12 2022-01-10Fix Astro Preview Pathing Issues (#2338)Gravatar Jonathan Neal 5-144/+150 * Fix preview issues triggered by pageUrlFormat & trailingSlash options * format * changeset * nit: fix host message 2022-01-10[ci] collect statsGravatar FredKSchott 1-0/+1 2022-01-09[ci] collect statsGravatar FredKSchott 1-0/+1 2022-01-08[ci] update lockfile (#2344)Gravatar Fred K. Schott 1-33/+33 Co-authored-by: FredKSchott <FredKSchott@users.noreply.github.com> 2022-01-08Fix sitemap.xml page urls (#2335)Gravatar Jonathan Neal 4-4/+8 * For pages, use the expected pathname, not the file name * changeset 2022-01-08[ci] collect statsGravatar FredKSchott 1-0/+1 2022-01-07Create .git-blame-ignore-revs (#2254)Gravatar Jonathan Neal 2-0/+8 * Create .git-blame-ignore-revs * docs: add note about `.git-blame-ignore-revs` Co-authored-by: Nate Moore <nate@skypack.dev> 2022-01-07Fix issue with plugins running twice in dev and build (#2323)Gravatar Jonathan Neal 2-2/+5 * Fix issue with plugins running twice in dev and build * nit: only patch plugins * nit: only patch plugins * nit: only solve for create-vite * nit: only solve for create-vite * Create seven-mice-do.md Co-authored-by: Fred K. Schott <fkschott@gmail.com> 2022-01-07[ci] yarn formatGravatar matthewp 1-8/+8 2022-01-07[ci] release (#2339)astro@0.22.9Gravatar github-actions[bot] 28-39/+40 Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> 2022-01-07[ci] yarn formatGravatar matthewp 3-7/+8 2022-01-07Handle loading the Code package in the static build (#2337)Gravatar Matthew Phillips 8-4/+87 * Handle loading the Code package Fixes #2329 * Use Code the normal way * Adds a changeset * Only resolve browser path if there is no common ancestor * Update examples/fast-build/src/pages/index.astro Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com> Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com> 2022-01-07[ci] update lockfile (#2334)Gravatar Fred K. Schott 1-154/+154 Co-authored-by: FredKSchott <FredKSchott@users.noreply.github.com> 2022-01-07[ci] yarn formatGravatar matthewp 1-8/+8 2022-01-07[ci] release (#2333)astro@0.22.8Gravatar github-actions[bot] 28-39/+40 Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> 2022-01-07[ci] collect statsGravatar FredKSchott 1-0/+1 2022-01-06[ci] yarn formatGravatar matthewp 4-54/+54 2022-01-06[ci] update lockfile (#2327)Gravatar Fred K. Schott 1-58/+64 Co-authored-by: FredKSchott <FredKSchott@users.noreply.github.com> 2022-01-06Fix subpath support regressions (#2330)Gravatar Matthew Phillips 12-22/+566 * Fix subpath support regressions * Adds a changeset * Update tests to reflect relative URL change * Pick a different port and hopefully windows works * Remove bad lint warning * Better handling of relative paths * or * Fixes use with pageUrlFormat * Update the pageDirectoryUrl test 2022-01-06[ci] yarn formatGravatar natemoo-re 1-2/+2 2022-01-06Added "IntelliSense for TypeScript" (#2326)astro@0.22.7Gravatar Morritz 1-0/+17 Important knowledge to avoid type errors. 2022-01-06[ci] collect statsGravatar FredKSchott 1-0/+1 2022-01-06[ci] yarn formatGravatar FredKSchott 1-8/+8 2022-01-05[ci] release (#2320)Gravatar github-actions[bot] 31-54/+46 Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> 2022-01-05chore: update compiler (#2324)Gravatar Nate Moore 3-5/+10