diff options
author | 2024-08-29 19:58:06 +0200 | |
---|---|---|
committer | 2024-08-29 19:58:06 +0200 | |
commit | b2d097b51e1d8845d955cee4d1e8838f96975638 (patch) | |
tree | 1593bbc71f60058579ed35219adf53b68ee3a24b /packages/integrations/node/src/preview.ts | |
parent | 93a1db68cd9cf3bb2a4d9f7a8af13cbd881eb701 (diff) | |
parent | 7897044c1d95ef905a4835dafe75d5b5b323b5bf (diff) | |
download | astro-b2d097b51e1d8845d955cee4d1e8838f96975638.tar.gz astro-b2d097b51e1d8845d955cee4d1e8838f96975638.tar.zst astro-b2d097b51e1d8845d955cee4d1e8838f96975638.zip |
Merge `vercel` and `node` into main #366
Diffstat (limited to 'packages/integrations/node/src/preview.ts')
-rw-r--r-- | packages/integrations/node/src/preview.ts | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/packages/integrations/node/src/preview.ts b/packages/integrations/node/src/preview.ts new file mode 100644 index 000000000..7e9415df8 --- /dev/null +++ b/packages/integrations/node/src/preview.ts @@ -0,0 +1,63 @@ +import { fileURLToPath } from 'node:url'; +import type { CreatePreviewServer } from 'astro'; +import { AstroError } from 'astro/errors'; +import { logListeningOn } from './log-listening-on.js'; +import type { createExports } from './server.js'; +import { createServer } from './standalone.js'; + +type ServerModule = ReturnType<typeof createExports>; +type MaybeServerModule = Partial<ServerModule>; + +const createPreviewServer: CreatePreviewServer = async (preview) => { + let ssrHandler: ServerModule['handler']; + let options: ServerModule['options']; + try { + process.env.ASTRO_NODE_AUTOSTART = 'disabled'; + const ssrModule: MaybeServerModule = await import(preview.serverEntrypoint.toString()); + if (typeof ssrModule.handler === 'function') { + ssrHandler = ssrModule.handler; + // biome-ignore lint/style/noNonNullAssertion: <explanation> + options = ssrModule.options!; + } else { + throw new AstroError( + `The server entrypoint doesn't have a handler. Are you sure this is the right file?` + ); + } + } catch (err) { + if ((err as any).code === 'ERR_MODULE_NOT_FOUND') { + throw new AstroError( + `The server entrypoint ${fileURLToPath( + preview.serverEntrypoint + )} does not exist. Have you ran a build yet?` + ); + // biome-ignore lint/style/noUselessElse: <explanation> + } else { + throw err; + } + } + const host = preview.host ?? 'localhost'; + const port = preview.port ?? 4321; + const server = createServer(ssrHandler, host, port); + + // If user specified custom headers append a listener + // to the server to add those headers to response + if (preview.headers) { + server.server.addListener('request', (_, res) => { + if (res.statusCode === 200) { + for (const [name, value] of Object.entries(preview.headers ?? {})) { + if (value) res.setHeader(name, value); + } + } + }); + } + + logListeningOn(preview.logger, server.server, options); + await new Promise<void>((resolve, reject) => { + server.server.once('listening', resolve); + server.server.once('error', reject); + server.server.listen(port, host); + }); + return server; +}; + +export { createPreviewServer as default }; |