Skip to content

Commit

Permalink
Make it deployable to Netlify (#2931)
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewp authored Mar 29, 2022
1 parent f89dc5c commit ecbcc8c
Show file tree
Hide file tree
Showing 18 changed files with 133 additions and 154 deletions.
13 changes: 0 additions & 13 deletions examples/ssr/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,4 @@ import nodejs from '@astrojs/node';
export default defineConfig({
adapter: nodejs(),
integrations: [svelte()],
vite: {
server: {
cors: {
credentials: true,
},
proxy: {
'/api': {
target: 'http://127.0.0.1:8085',
changeOrigin: true,
},
},
},
},
});
4 changes: 1 addition & 3 deletions examples/ssr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
"version": "0.0.1",
"private": true,
"scripts": {
"dev-api": "node server/dev-api.mjs",
"dev-server": "astro dev --experimental-ssr",
"dev": "concurrently \"npm run dev-api\" \"astro dev --experimental-ssr\"",
"dev": "astro dev --experimental-ssr",
"start": "astro dev",
"build": "astro build --experimental-ssr",
"server": "node server/server.mjs"
Expand Down
100 changes: 0 additions & 100 deletions examples/ssr/server/api.mjs

This file was deleted.

17 changes: 0 additions & 17 deletions examples/ssr/server/dev-api.mjs

This file was deleted.

33 changes: 16 additions & 17 deletions examples/ssr/server/server.mjs
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
import { createServer } from 'http';
import fs from 'fs';
import mime from 'mime';
import { apiHandler } from './api.mjs';
import { handler as ssrHandler } from '../dist/server/entry.mjs';

const clientRoot = new URL('../dist/client/', import.meta.url);

async function handle(req, res) {
ssrHandler(req, res, async () => {
// Did not match an SSR route
ssrHandler(req, res, async (err) => {
if(err) {
res.writeHead(500);
res.end(err.stack)
return;
}

if (/^\/api\//.test(req.url)) {
return apiHandler(req, res);
} else {
let local = new URL('.' + req.url, clientRoot);
try {
const data = await fs.promises.readFile(local);
res.writeHead(200, {
'Content-Type': mime.getType(req.url),
});
res.end(data);
} catch {
res.writeHead(404);
res.end();
}
let local = new URL('.' + req.url, clientRoot);
try {
const data = await fs.promises.readFile(local);
res.writeHead(200, {
'Content-Type': mime.getType(req.url),
});
res.end(data);
} catch {
res.writeHead(404);
res.end();
}
});
}
Expand Down
2 changes: 1 addition & 1 deletion examples/ssr/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export async function getCart(): Promise<Cart> {
}

export async function addToUserCart(id: number | string, name: string): Promise<void> {
await fetch(`${origin}/api/add-to-cart`, {
await fetch(`${origin}/api/cart`, {
credentials: 'same-origin',
method: 'POST',
mode: 'no-cors',
Expand Down
File renamed without changes.
9 changes: 9 additions & 0 deletions examples/ssr/src/models/db.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import db from './db.json';

const products = db.products;
const productMap = new Map(products.map((product) => [product.id, product]));

export {
products,
productMap
};
3 changes: 3 additions & 0 deletions examples/ssr/src/models/session.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

// Normally this would be in a database.
export const userCartItems = new Map();
47 changes: 47 additions & 0 deletions examples/ssr/src/pages/api/cart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import lightcookie from 'lightcookie';
import { userCartItems } from '../../models/session';

export function get(_params: any, request: Request) {
let cookie = request.headers.get('cookie');
let userId = cookie ? lightcookie.parse(cookie)['user-id'] : '1'; // default for testing
if (!userId || !userCartItems.has(userId)) {
return {
body: JSON.stringify({ items: [] })
};
}
let items = userCartItems.get(userId);
let array = Array.from(items.values());

return {
body: JSON.stringify({ items: array })
}
}

interface AddToCartItem {
id: number;
name: string;
}

export async function post(_params: any, request: Request) {
const item: AddToCartItem = await request.json();

let cookie = request.headers.get('cookie');
let userId = lightcookie.parse(cookie)['user-id'];

if (!userCartItems.has(userId)) {
userCartItems.set(userId, new Map());
}

let cart = userCartItems.get(userId);
if (cart.has(item.id)) {
cart.get(item.id).count++;
} else {
cart.set(item.id, { id: item.id, name: item.name, count: 1 });
}

return {
body: JSON.stringify({
ok: true
})
};
}
7 changes: 7 additions & 0 deletions examples/ssr/src/pages/api/products.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { products } from '../../models/db';

export function get() {
return {
body: JSON.stringify(products)
};
}
17 changes: 17 additions & 0 deletions examples/ssr/src/pages/api/products/[id].ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { productMap } from '../../../models/db';

export function get({ id: idStr }) {
const id = Number(idStr);
if (productMap.has(id)) {
const product = productMap.get(id);

return {
body: JSON.stringify(product)
};
} else {
return new Response(null, {
status: 400,
statusText: 'Not found'
});
}
}
1 change: 1 addition & 0 deletions examples/ssr/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"lib": ["ES2015", "DOM"],
"module": "ES2022",
"moduleResolution": "node",
"resolveJsonModule": true,
"types": ["astro/env"]
}
}
1 change: 1 addition & 0 deletions packages/astro/src/core/build/vite-plugin-ssr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const manifestReplace = '@@ASTRO_MANIFEST_REPLACE@@';
export function vitePluginSSR(buildOpts: StaticBuildOptions, internals: BuildInternals, adapter: AstroAdapter): VitePlugin {
return {
name: '@astrojs/vite-plugin-astro-ssr',
enforce: 'post',
options(opts) {
return addRollupInput(opts, [virtualModuleId]);
},
Expand Down
5 changes: 4 additions & 1 deletion packages/astro/src/core/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,23 @@ import type { LogOptions } from './logger';
import { warn } from './logger.js';

type HeaderType = Headers | Record<string, any> | IncomingHttpHeaders;
type RequestBody = ArrayBuffer | Blob | ReadableStream | URLSearchParams | FormData;

export interface CreateRequestOptions {
url: URL | string;
headers: HeaderType;
method?: string;
body?: RequestBody | undefined;
logging: LogOptions;
}

export function createRequest({ url, headers, method = 'GET', logging }: CreateRequestOptions): Request {
export function createRequest({ url, headers, method = 'GET', body = undefined, logging }: CreateRequestOptions): Request {
let headersObj = headers instanceof Headers ? headers : new Headers(Object.entries(headers as Record<string, any>));

const request = new Request(url.toString(), {
method: method,
headers: headersObj,
body
});

Object.defineProperties(request, {
Expand Down
12 changes: 12 additions & 0 deletions packages/astro/src/vite-plugin-astro-server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,23 @@ async function handleRequest(
}
}

let body: ArrayBuffer | undefined = undefined;
if(!(req.method === 'GET' || req.method === 'HEAD')) {
let bytes: string[] = [];
await new Promise(resolve => {
req.setEncoding('utf-8');
req.on('data', bts => bytes.push(bts));
req.on('close', resolve);
});
body = new TextEncoder().encode(bytes.join('')).buffer;
}

// Headers are only available when using SSR.
const request = createRequest({
url,
headers: buildingToSSR ? req.headers : new Headers(),
method: req.method,
body,
logging,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const val = Number(Astro.params.id);
<html>
<head>
<title>Test app</title>
<style>body { font-size: 11px; }</style>
</head>
<body>
<h1>Item { val }</h1>
Expand Down
15 changes: 13 additions & 2 deletions packages/astro/test/ssr-dynamic.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,23 @@ describe('Dynamic pages in SSR', () => {
await fixture.build();
});

it('Do not have to implement getStaticPaths', async () => {
async function fetchHTML(path) {
const app = await fixture.loadTestAdapterApp();
const request = new Request('http://example.com/123');
const request = new Request('http://example.com' + path);
const response = await app.render(request);
const html = await response.text();
return html;
}

it('Do not have to implement getStaticPaths', async () => {
const html = await fetchHTML('/123');
const $ = cheerioLoad(html);
expect($('h1').text()).to.equal('Item 123');
});

it('Includes page styles', async () => {
const html = await fetchHTML('/123');
const $ = cheerioLoad(html);
expect($('link').length).to.equal(1);
});
});

0 comments on commit ecbcc8c

Please sign in to comment.