mirror of
https://github.com/withastro/astro.git
synced 2025-03-10 23:01:26 -05:00
Merge branch 'main' into next
This commit is contained in:
commit
7f978ec9d9
14 changed files with 243 additions and 34 deletions
|
@ -39,6 +39,15 @@
|
|||
- Updated dependencies [[`1eae2e3f7`](https://github.com/withastro/astro/commit/1eae2e3f7d693c9dfe91c8ccfbe606d32bf2fb81), [`76ddef19c`](https://github.com/withastro/astro/commit/76ddef19ccab6e5f7d3a5740cd41acf10e334b38), [`9b4f70a62`](https://github.com/withastro/astro/commit/9b4f70a629f55e461759ba46f68af7097a2e9215), [`3fdf509b2`](https://github.com/withastro/astro/commit/3fdf509b2731a9b2f972d89291e57cf78d62c769), [`2f951cd40`](https://github.com/withastro/astro/commit/2f951cd403dfcc2c3ca6aae618ae3e1409516e32), [`c022a4217`](https://github.com/withastro/astro/commit/c022a4217a805d223c1494e9eda4e48bbf810388), [`67becaa58`](https://github.com/withastro/astro/commit/67becaa580b8f787df58de66b7008b7098f1209c), [`bc37331d8`](https://github.com/withastro/astro/commit/bc37331d8154e3e95a8df9131e4e014e78a7a9e7), [`dfc2d93e3`](https://github.com/withastro/astro/commit/dfc2d93e3c645995379358fabbdfa9aab99f43d8), [`3dc1ca2fa`](https://github.com/withastro/astro/commit/3dc1ca2fac8d9965cc5085a5d09e72ed87b4281a), [`1be84dfee`](https://github.com/withastro/astro/commit/1be84dfee3ce8e6f5cc624f99aec4e980f6fde37), [`35f01df79`](https://github.com/withastro/astro/commit/35f01df797d23315f2bee2fc3fd795adb0559c58), [`3fdf509b2`](https://github.com/withastro/astro/commit/3fdf509b2731a9b2f972d89291e57cf78d62c769), [`78de801f2`](https://github.com/withastro/astro/commit/78de801f21fd4ca1653950027d953bf08614566b), [`59d6e569f`](https://github.com/withastro/astro/commit/59d6e569f63e175c97e82e94aa7974febfb76f7c), [`7723c4cc9`](https://github.com/withastro/astro/commit/7723c4cc93298c2e6530e55da7afda048f22cf81), [`fb5cd6b56`](https://github.com/withastro/astro/commit/fb5cd6b56dc27a71366ed5e1ab8bfe9b8f96bac5), [`631b9c410`](https://github.com/withastro/astro/commit/631b9c410d5d66fa384674027ba95d69ebb5063f)]:
|
||||
- astro@3.0.0-beta.0
|
||||
|
||||
## 5.3.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#8084](https://github.com/withastro/astro/pull/8084) [`560e45924`](https://github.com/withastro/astro/commit/560e45924622141206ff5b47d134cb343d6d2a71) Thanks [@hbgl](https://github.com/hbgl)! - Stream request body instead of buffering it in memory.
|
||||
|
||||
- Updated dependencies [[`c19987df0`](https://github.com/withastro/astro/commit/c19987df0be3520cf774476cea270c03edd08354), [`560e45924`](https://github.com/withastro/astro/commit/560e45924622141206ff5b47d134cb343d6d2a71), [`afc45af20`](https://github.com/withastro/astro/commit/afc45af2022f7c43fbb6c5c04983695f3819e47e), [`d1f7143f9`](https://github.com/withastro/astro/commit/d1f7143f9caf2ffa0e87cc55c0e05339d3501db3), [`3e46634fd`](https://github.com/withastro/astro/commit/3e46634fd540e5b967d2e5c9abd6235452cee2f2), [`a12027b6a`](https://github.com/withastro/astro/commit/a12027b6af411be39700919ca47e240a335e9887)]:
|
||||
- astro@2.10.8
|
||||
|
||||
## 5.3.3
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
"chai": "^4.3.7",
|
||||
"cheerio": "1.0.0-rc.12",
|
||||
"mocha": "^9.2.2",
|
||||
"node-mocks-http": "^1.12.2"
|
||||
"node-mocks-http": "^1.13.0",
|
||||
"undici": "^5.22.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import nodejs from '../dist/index.js';
|
||||
import { loadFixture, createRequestAndResponse } from './test-utils.js';
|
||||
import { expect } from 'chai';
|
||||
import crypto from 'node:crypto';
|
||||
|
||||
describe('API routes', () => {
|
||||
/** @type {import('./test-utils').Fixture} */
|
||||
|
@ -22,9 +23,11 @@ describe('API routes', () => {
|
|||
url: '/recipes',
|
||||
});
|
||||
|
||||
handler(req, res);
|
||||
req.once('async_iterator', () => {
|
||||
req.send(JSON.stringify({ id: 2 }));
|
||||
});
|
||||
|
||||
req.send(JSON.stringify({ id: 2 }));
|
||||
handler(req, res);
|
||||
|
||||
let [buffer] = await done;
|
||||
|
||||
|
@ -43,11 +46,47 @@ describe('API routes', () => {
|
|||
url: '/binary',
|
||||
});
|
||||
|
||||
req.once('async_iterator', () => {
|
||||
req.send(Buffer.from(new Uint8Array([1, 2, 3, 4, 5])));
|
||||
});
|
||||
|
||||
handler(req, res);
|
||||
req.send(Buffer.from(new Uint8Array([1, 2, 3, 4, 5])));
|
||||
|
||||
let [out] = await done;
|
||||
let arr = Array.from(new Uint8Array(out.buffer));
|
||||
expect(arr).to.deep.equal([5, 4, 3, 2, 1]);
|
||||
});
|
||||
|
||||
it('Can post large binary data', async () => {
|
||||
const { handler } = await import('./fixtures/api-route/dist/server/entry.mjs');
|
||||
|
||||
let { req, res, done } = createRequestAndResponse({
|
||||
method: 'POST',
|
||||
url: '/hash',
|
||||
});
|
||||
|
||||
handler(req, res);
|
||||
|
||||
let expectedDigest = null;
|
||||
req.once('async_iterator', () => {
|
||||
// Send 256MB of garbage data in 256KB chunks. This should be fast (< 1sec).
|
||||
let remainingBytes = 256 * 1024 * 1024;
|
||||
const chunkSize = 256 * 1024;
|
||||
|
||||
const hash = crypto.createHash('sha256');
|
||||
while (remainingBytes > 0) {
|
||||
const size = Math.min(remainingBytes, chunkSize);
|
||||
const chunk = Buffer.alloc(size, Math.floor(Math.random() * 256));
|
||||
hash.update(chunk);
|
||||
req.emit('data', chunk);
|
||||
remainingBytes -= size;
|
||||
}
|
||||
|
||||
req.emit('end');
|
||||
expectedDigest = hash.digest();
|
||||
});
|
||||
|
||||
let [out] = await done;
|
||||
expect(new Uint8Array(out.buffer)).to.deep.equal(expectedDigest);
|
||||
});
|
||||
});
|
||||
|
|
16
packages/integrations/node/test/fixtures/api-route/src/pages/hash.ts
vendored
Normal file
16
packages/integrations/node/test/fixtures/api-route/src/pages/hash.ts
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
import crypto from 'node:crypto';
|
||||
|
||||
export async function post({ request }: { request: Request }) {
|
||||
const hash = crypto.createHash('sha256');
|
||||
|
||||
const iterable = request.body as unknown as AsyncIterable<Uint8Array>;
|
||||
for await (const chunk of iterable) {
|
||||
hash.update(chunk);
|
||||
}
|
||||
|
||||
return new Response(hash.digest(), {
|
||||
headers: {
|
||||
'Content-Type': 'application/octet-stream'
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"name": "@test/nodejs-prerender-404",
|
||||
"name": "@test/nodejs-prerender-404-500",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/node": "workspace:*"
|
3
packages/integrations/node/test/fixtures/prerender-404-500/src/external-stylesheet.css
vendored
Normal file
3
packages/integrations/node/test/fixtures/prerender-404-500/src/external-stylesheet.css
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
body {
|
||||
background-color: ivory;
|
||||
}
|
17
packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-404.ts
vendored
Normal file
17
packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-404.ts
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
// This module is only used by the prerendered 404.astro.
|
||||
// It exhibits different behavior if it's called more than once,
|
||||
// which is detected by a test and interpreted as a failure.
|
||||
|
||||
let usedOnce = false
|
||||
let dynamicMessage = "Page was not prerendered"
|
||||
|
||||
export default function () {
|
||||
if (usedOnce === false) {
|
||||
usedOnce = true
|
||||
return "Page does not exist"
|
||||
}
|
||||
|
||||
dynamicMessage += "+"
|
||||
|
||||
return dynamicMessage
|
||||
}
|
17
packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-500.ts
vendored
Normal file
17
packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-500.ts
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
// This module is only used by the prerendered 500.astro.
|
||||
// It exhibits different behavior if it's called more than once,
|
||||
// which is detected by a test and interpreted as a failure.
|
||||
|
||||
let usedOnce = false
|
||||
let dynamicMessage = "Page was not prerendered"
|
||||
|
||||
export default function () {
|
||||
if (usedOnce === false) {
|
||||
usedOnce = true
|
||||
return "Something went wrong"
|
||||
}
|
||||
|
||||
dynamicMessage += "+"
|
||||
|
||||
return dynamicMessage
|
||||
}
|
5
packages/integrations/node/test/fixtures/prerender-404-500/src/pages/404.astro
vendored
Normal file
5
packages/integrations/node/test/fixtures/prerender-404-500/src/pages/404.astro
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
import message from "../nondeterminism-404"
|
||||
export const prerender = true;
|
||||
---
|
||||
{message()}
|
6
packages/integrations/node/test/fixtures/prerender-404-500/src/pages/500.astro
vendored
Normal file
6
packages/integrations/node/test/fixtures/prerender-404-500/src/pages/500.astro
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
import "../external-stylesheet.css"
|
||||
import message from "../nondeterminism-500"
|
||||
export const prerender = true
|
||||
---
|
||||
<h1>{message()}</h1>
|
4
packages/integrations/node/test/fixtures/prerender-404-500/src/pages/fivehundred.astro
vendored
Normal file
4
packages/integrations/node/test/fixtures/prerender-404-500/src/pages/fivehundred.astro
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
return new Response(null, { status: 500 })
|
||||
---
|
||||
<p>This html will not be served</p>
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
export const prerender = true;
|
||||
---
|
||||
|
||||
Page does not exist
|
|
@ -9,10 +9,11 @@ import * as cheerio from 'cheerio';
|
|||
|
||||
async function load() {
|
||||
const mod = await import(
|
||||
`./fixtures/prerender-404/dist/server/entry.mjs?dropcache=${Date.now()}`
|
||||
`./fixtures/prerender-404-500/dist/server/entry.mjs?dropcache=${Date.now()}`
|
||||
);
|
||||
return mod;
|
||||
}
|
||||
|
||||
describe('Prerender 404', () => {
|
||||
/** @type {import('./test-utils').Fixture} */
|
||||
let fixture;
|
||||
|
@ -24,8 +25,12 @@ describe('Prerender 404', () => {
|
|||
process.env.PRERENDER = true;
|
||||
|
||||
fixture = await loadFixture({
|
||||
// inconsequential config that differs between tests
|
||||
// to bust cache and prevent modules and their state
|
||||
// from being reused
|
||||
site: 'https://test.dev/',
|
||||
base: '/some-base',
|
||||
root: './fixtures/prerender-404/',
|
||||
root: './fixtures/prerender-404-500/',
|
||||
output: 'server',
|
||||
adapter: nodejs({ mode: 'standalone' }),
|
||||
});
|
||||
|
@ -51,12 +56,52 @@ describe('Prerender 404', () => {
|
|||
});
|
||||
|
||||
it('Can handle prerendered 404', async () => {
|
||||
const res = await fetch(`http://${server.host}:${server.port}/some-base/missing`);
|
||||
const html = await res.text();
|
||||
const url = `http://${server.host}:${server.port}/some-base/missing`;
|
||||
const res1 = await fetch(url);
|
||||
const res2 = await fetch(url);
|
||||
const res3 = await fetch(url);
|
||||
|
||||
expect(res1.status).to.equal(404);
|
||||
expect(res2.status).to.equal(404);
|
||||
expect(res3.status).to.equal(404);
|
||||
|
||||
const html1 = await res1.text();
|
||||
const html2 = await res2.text();
|
||||
const html3 = await res3.text();
|
||||
|
||||
expect(html1).to.equal(html2);
|
||||
expect(html2).to.equal(html3);
|
||||
|
||||
const $ = cheerio.load(html1);
|
||||
|
||||
expect($('body').text()).to.equal('Page does not exist');
|
||||
});
|
||||
|
||||
it(' Can handle prerendered 500 called indirectly', async () => {
|
||||
const url = `http://${server.host}:${server.port}/some-base/fivehundred`;
|
||||
const response1 = await fetch(url);
|
||||
const response2 = await fetch(url);
|
||||
const response3 = await fetch(url);
|
||||
|
||||
expect(response1.status).to.equal(500);
|
||||
|
||||
const html1 = await response1.text();
|
||||
const html2 = await response2.text();
|
||||
const html3 = await response3.text();
|
||||
|
||||
expect(html1).to.contain('Something went wrong');
|
||||
|
||||
expect(html1).to.equal(html2);
|
||||
expect(html2).to.equal(html3);
|
||||
});
|
||||
|
||||
it('prerendered 500 page includes expected styles', async () => {
|
||||
const response = await fetch(`http://${server.host}:${server.port}/some-base/fivehundred`);
|
||||
const html = await response.text();
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
expect(res.status).to.equal(404);
|
||||
expect($('body').text()).to.equal('Page does not exist');
|
||||
// length will be 0 if the stylesheet does not get included
|
||||
expect($('link[rel=stylesheet]')).to.have.a.lengthOf(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -66,12 +111,16 @@ describe('Prerender 404', () => {
|
|||
process.env.PRERENDER = true;
|
||||
|
||||
fixture = await loadFixture({
|
||||
root: './fixtures/prerender-404/',
|
||||
// inconsequential config that differs between tests
|
||||
// to bust cache and prevent modules and their state
|
||||
// from being reused
|
||||
site: 'https://test.info/',
|
||||
root: './fixtures/prerender-404-500/',
|
||||
output: 'server',
|
||||
adapter: nodejs({ mode: 'standalone' }),
|
||||
});
|
||||
await fixture.build();
|
||||
const { startServer } = await await load();
|
||||
const { startServer } = await load();
|
||||
let res = startServer();
|
||||
server = res.server;
|
||||
});
|
||||
|
@ -92,11 +141,24 @@ describe('Prerender 404', () => {
|
|||
});
|
||||
|
||||
it('Can handle prerendered 404', async () => {
|
||||
const res = await fetch(`http://${server.host}:${server.port}/missing`);
|
||||
const html = await res.text();
|
||||
const $ = cheerio.load(html);
|
||||
const url = `http://${server.host}:${server.port}/some-base/missing`;
|
||||
const res1 = await fetch(url);
|
||||
const res2 = await fetch(url);
|
||||
const res3 = await fetch(url);
|
||||
|
||||
expect(res1.status).to.equal(404);
|
||||
expect(res2.status).to.equal(404);
|
||||
expect(res3.status).to.equal(404);
|
||||
|
||||
const html1 = await res1.text();
|
||||
const html2 = await res2.text();
|
||||
const html3 = await res3.text();
|
||||
|
||||
expect(html1).to.equal(html2);
|
||||
expect(html2).to.equal(html3);
|
||||
|
||||
const $ = cheerio.load(html1);
|
||||
|
||||
expect(res.status).to.equal(404);
|
||||
expect($('body').text()).to.equal('Page does not exist');
|
||||
});
|
||||
});
|
||||
|
@ -112,13 +174,17 @@ describe('Hybrid 404', () => {
|
|||
process.env.ASTRO_NODE_AUTOSTART = 'disabled';
|
||||
process.env.PRERENDER = false;
|
||||
fixture = await loadFixture({
|
||||
// inconsequential config that differs between tests
|
||||
// to bust cache and prevent modules and their state
|
||||
// from being reused
|
||||
site: 'https://test.com/',
|
||||
base: '/some-base',
|
||||
root: './fixtures/prerender-404/',
|
||||
root: './fixtures/prerender-404-500/',
|
||||
output: 'hybrid',
|
||||
adapter: nodejs({ mode: 'standalone' }),
|
||||
});
|
||||
await fixture.build();
|
||||
const { startServer } = await await load();
|
||||
const { startServer } = await load();
|
||||
let res = startServer();
|
||||
server = res.server;
|
||||
});
|
||||
|
@ -139,11 +205,24 @@ describe('Hybrid 404', () => {
|
|||
});
|
||||
|
||||
it('Can handle prerendered 404', async () => {
|
||||
const res = await fetch(`http://${server.host}:${server.port}/some-base/missing`);
|
||||
const html = await res.text();
|
||||
const $ = cheerio.load(html);
|
||||
const url = `http://${server.host}:${server.port}/some-base/missing`;
|
||||
const res1 = await fetch(url);
|
||||
const res2 = await fetch(url);
|
||||
const res3 = await fetch(url);
|
||||
|
||||
expect(res1.status).to.equal(404);
|
||||
expect(res2.status).to.equal(404);
|
||||
expect(res3.status).to.equal(404);
|
||||
|
||||
const html1 = await res1.text();
|
||||
const html2 = await res2.text();
|
||||
const html3 = await res3.text();
|
||||
|
||||
expect(html1).to.equal(html2);
|
||||
expect(html2).to.equal(html3);
|
||||
|
||||
const $ = cheerio.load(html1);
|
||||
|
||||
expect(res.status).to.equal(404);
|
||||
expect($('body').text()).to.equal('Page does not exist');
|
||||
});
|
||||
});
|
||||
|
@ -153,12 +232,16 @@ describe('Hybrid 404', () => {
|
|||
process.env.ASTRO_NODE_AUTOSTART = 'disabled';
|
||||
process.env.PRERENDER = false;
|
||||
fixture = await loadFixture({
|
||||
root: './fixtures/prerender-404/',
|
||||
// inconsequential config that differs between tests
|
||||
// to bust cache and prevent modules and their state
|
||||
// from being reused
|
||||
site: 'https://test.net/',
|
||||
root: './fixtures/prerender-404-500/',
|
||||
output: 'hybrid',
|
||||
adapter: nodejs({ mode: 'standalone' }),
|
||||
});
|
||||
await fixture.build();
|
||||
const { startServer } = await await load();
|
||||
const { startServer } = await load();
|
||||
let res = startServer();
|
||||
server = res.server;
|
||||
});
|
||||
|
@ -179,11 +262,24 @@ describe('Hybrid 404', () => {
|
|||
});
|
||||
|
||||
it('Can handle prerendered 404', async () => {
|
||||
const res = await fetch(`http://${server.host}:${server.port}/missing`);
|
||||
const html = await res.text();
|
||||
const $ = cheerio.load(html);
|
||||
const url = `http://${server.host}:${server.port}/missing`;
|
||||
const res1 = await fetch(url);
|
||||
const res2 = await fetch(url);
|
||||
const res3 = await fetch(url);
|
||||
|
||||
expect(res1.status).to.equal(404);
|
||||
expect(res2.status).to.equal(404);
|
||||
expect(res3.status).to.equal(404);
|
||||
|
||||
const html1 = await res1.text();
|
||||
const html2 = await res2.text();
|
||||
const html3 = await res3.text();
|
||||
|
||||
expect(html1).to.equal(html2);
|
||||
expect(html2).to.equal(html3);
|
||||
|
||||
const $ = cheerio.load(html1);
|
||||
|
||||
expect(res.status).to.equal(404);
|
||||
expect($('body').text()).to.equal('Page does not exist');
|
||||
});
|
||||
});
|
Loading…
Add table
Reference in a new issue