summaryrefslogtreecommitdiff
path: root/packages/integrations/node/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/integrations/node/src')
-rw-r--r--packages/integrations/node/src/index.ts20
-rw-r--r--packages/integrations/node/src/server.ts48
2 files changed, 68 insertions, 0 deletions
diff --git a/packages/integrations/node/src/index.ts b/packages/integrations/node/src/index.ts
new file mode 100644
index 000000000..903d5b1cc
--- /dev/null
+++ b/packages/integrations/node/src/index.ts
@@ -0,0 +1,20 @@
+import type { AstroAdapter, AstroIntegration } from 'astro';
+
+export function getAdapter(): AstroAdapter {
+ return {
+ name: '@astrojs/node',
+ serverEntrypoint: '@astrojs/node/server.js',
+ exports: ['handler'],
+ };
+}
+
+export default function createIntegration(): AstroIntegration {
+ return {
+ name: '@astrojs/node',
+ hooks: {
+ 'astro:config:done': ({ setAdapter }) => {
+ setAdapter(getAdapter());
+ }
+ }
+ };
+}
diff --git a/packages/integrations/node/src/server.ts b/packages/integrations/node/src/server.ts
new file mode 100644
index 000000000..791dc58b2
--- /dev/null
+++ b/packages/integrations/node/src/server.ts
@@ -0,0 +1,48 @@
+import type { SSRManifest } from 'astro';
+import type { IncomingMessage, ServerResponse } from 'http';
+import { NodeApp } from 'astro/app/node';
+import { polyfill } from '@astrojs/webapi';
+
+polyfill(globalThis, {
+ exclude: 'window document'
+});
+
+export function createExports(manifest: SSRManifest) {
+ const app = new NodeApp(manifest, new URL(import.meta.url));
+ return {
+ async handler(req: IncomingMessage, res: ServerResponse, next?: (err?: unknown) => void) {
+ const route = app.match(req);
+
+ if(route) {
+ try {
+ const response = await app.render(req);
+ await writeWebResponse(res, response);
+ } catch(err: unknown) {
+ if(next) {
+ next(err);
+ } else {
+ throw err;
+ }
+ }
+ } else if(next) {
+ return next();
+ }
+ }
+ }
+}
+
+async function writeWebResponse(res: ServerResponse, webResponse: Response) {
+ const { status, headers, body } = webResponse;
+ res.writeHead(status, Object.fromEntries(headers.entries()));
+ if (body) {
+ const reader = body.getReader();
+ while (true) {
+ const { done, value } = await reader.read();
+ if (done) break;
+ if (value) {
+ res.write(value);
+ }
+ }
+ }
+ res.end();
+}