refactor: use new Astro internals (#8254)
* refactor: use new Astro internals * chore: update tests --------- Co-authored-by: Matthew Phillips <matthew@skypack.dev>
This commit is contained in:
parent
52f0837bde
commit
c7921e9e1b
10 changed files with 34 additions and 68 deletions
|
@ -24,6 +24,8 @@ import type { AstroIntegrationLogger, Logger, LoggerLevel } from '../core/logger
|
||||||
import type { AstroComponentFactory, AstroComponentInstance } from '../runtime/server';
|
import type { AstroComponentFactory, AstroComponentInstance } from '../runtime/server';
|
||||||
import type { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './../core/constants.js';
|
import type { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './../core/constants.js';
|
||||||
|
|
||||||
|
export { type AstroIntegrationLogger };
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
MarkdownHeading,
|
MarkdownHeading,
|
||||||
MarkdownMetadata,
|
MarkdownMetadata,
|
||||||
|
@ -2203,6 +2205,7 @@ export interface PreviewServerParams {
|
||||||
host: string | undefined;
|
host: string | undefined;
|
||||||
port: number;
|
port: number;
|
||||||
base: string;
|
base: string;
|
||||||
|
logger: AstroIntegrationLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CreatePreviewServer = (
|
export type CreatePreviewServer = (
|
||||||
|
|
|
@ -27,6 +27,7 @@ import { matchRoute } from '../routing/match.js';
|
||||||
import { EndpointNotFoundError, SSRRoutePipeline } from './ssrPipeline.js';
|
import { EndpointNotFoundError, SSRRoutePipeline } from './ssrPipeline.js';
|
||||||
import type { RouteInfo } from './types';
|
import type { RouteInfo } from './types';
|
||||||
export { deserializeManifest } from './common.js';
|
export { deserializeManifest } from './common.js';
|
||||||
|
import { AstroIntegrationLogger } from '../logger/core.js';
|
||||||
|
|
||||||
const clientLocalsSymbol = Symbol.for('astro.locals');
|
const clientLocalsSymbol = Symbol.for('astro.locals');
|
||||||
|
|
||||||
|
@ -58,6 +59,7 @@ export class App {
|
||||||
#pipeline: SSRRoutePipeline;
|
#pipeline: SSRRoutePipeline;
|
||||||
#onRequest: MiddlewareEndpointHandler | undefined;
|
#onRequest: MiddlewareEndpointHandler | undefined;
|
||||||
#middlewareLoaded: boolean;
|
#middlewareLoaded: boolean;
|
||||||
|
#adapterLogger: AstroIntegrationLogger;
|
||||||
|
|
||||||
constructor(manifest: SSRManifest, streaming = true) {
|
constructor(manifest: SSRManifest, streaming = true) {
|
||||||
this.#manifest = manifest;
|
this.#manifest = manifest;
|
||||||
|
@ -68,10 +70,14 @@ export class App {
|
||||||
this.#baseWithoutTrailingSlash = removeTrailingForwardSlash(this.#manifest.base);
|
this.#baseWithoutTrailingSlash = removeTrailingForwardSlash(this.#manifest.base);
|
||||||
this.#pipeline = new SSRRoutePipeline(this.#createEnvironment(streaming));
|
this.#pipeline = new SSRRoutePipeline(this.#createEnvironment(streaming));
|
||||||
this.#middlewareLoaded = false;
|
this.#middlewareLoaded = false;
|
||||||
|
this.#adapterLogger = new AstroIntegrationLogger(
|
||||||
|
this.#logger.options,
|
||||||
|
this.#manifest.adapterName
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
set setManifest(newManifest: SSRManifest) {
|
getAdapterLogger(): AstroIntegrationLogger {
|
||||||
this.#manifest = newManifest;
|
return this.#adapterLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { createNodeLogger } from '../config/logging.js';
|
||||||
import { createSettings } from '../config/settings.js';
|
import { createSettings } from '../config/settings.js';
|
||||||
import createStaticPreviewServer from './static-preview-server.js';
|
import createStaticPreviewServer from './static-preview-server.js';
|
||||||
import { getResolvedHostForHttpServer } from './util.js';
|
import { getResolvedHostForHttpServer } from './util.js';
|
||||||
|
import { AstroIntegrationLogger } from '../../core/logger/core.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts a local server to serve your static dist/ directory. This command is useful for previewing
|
* Starts a local server to serve your static dist/ directory. This command is useful for previewing
|
||||||
|
@ -62,6 +63,7 @@ export default async function preview(inlineConfig: AstroInlineConfig): Promise<
|
||||||
host: getResolvedHostForHttpServer(settings.config.server.host),
|
host: getResolvedHostForHttpServer(settings.config.server.host),
|
||||||
port: settings.config.server.port,
|
port: settings.config.server.port,
|
||||||
base: settings.config.base,
|
base: settings.config.base,
|
||||||
|
logger: new AstroIntegrationLogger(logger.options, settings.adapter.name),
|
||||||
});
|
});
|
||||||
|
|
||||||
return server;
|
return server;
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
// TODO: remove `getRuntime()` in Astro 3.0
|
|
||||||
import type { Cache, CacheStorage, IncomingRequestCfProperties } from '@cloudflare/workers-types';
|
|
||||||
|
|
||||||
export type WorkerRuntime<T = unknown> = {
|
|
||||||
name: 'cloudflare';
|
|
||||||
env: T;
|
|
||||||
waitUntil(promise: Promise<any>): void;
|
|
||||||
passThroughOnException(): void;
|
|
||||||
caches?: CacheStorage & { default: Cache };
|
|
||||||
cf?: IncomingRequestCfProperties;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type PagesRuntime<T = unknown, U = unknown> = {
|
|
||||||
name: 'cloudflare';
|
|
||||||
env: T;
|
|
||||||
functionPath: string;
|
|
||||||
params: Record<string, string>;
|
|
||||||
data: U;
|
|
||||||
waitUntil(promise: Promise<any>): void;
|
|
||||||
next(request: Request): void;
|
|
||||||
caches?: CacheStorage & { default: Cache };
|
|
||||||
cf?: IncomingRequestCfProperties;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated since version 6.8.0
|
|
||||||
* The `getRuntime` utility has been deprecated and should be updated to the new [`Astro.locals`](https://docs.astro.build/en/guides/middleware/#locals) API.
|
|
||||||
* ```diff
|
|
||||||
* - import { getRuntime } from '@astrojs/cloudflare/runtime';
|
|
||||||
* - getRuntime(Astro.request);
|
|
||||||
*
|
|
||||||
* + const runtime = Astro.locals.runtime;
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export function getRuntime<T = unknown, U = unknown>(
|
|
||||||
request: Request
|
|
||||||
): WorkerRuntime<T> | PagesRuntime<T, U> {
|
|
||||||
if (!!request) {
|
|
||||||
return Reflect.get(request, Symbol.for('runtime'));
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
|
||||||
'To retrieve the current cloudflare runtime you need to pass in the Astro request object'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,5 @@
|
||||||
---
|
---
|
||||||
import { getRuntime } from '@astrojs/cloudflare/runtime';
|
const runtime = Astro.locals.runtime;
|
||||||
const runtime = getRuntime(Astro.request);
|
|
||||||
---
|
---
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type { AstroAdapter, AstroIntegration } from 'astro';
|
import type { AstroAdapter, AstroIntegration } from 'astro';
|
||||||
import type { Options, UserOptions } from './types';
|
import type { Options, UserOptions } from './types';
|
||||||
|
import { AstroError } from 'astro/errors';
|
||||||
export function getAdapter(options: Options): AstroAdapter {
|
export function getAdapter(options: Options): AstroAdapter {
|
||||||
return {
|
return {
|
||||||
name: '@astrojs/node',
|
name: '@astrojs/node',
|
||||||
|
@ -23,7 +23,7 @@ export function getAdapter(options: Options): AstroAdapter {
|
||||||
|
|
||||||
export default function createIntegration(userOptions: UserOptions): AstroIntegration {
|
export default function createIntegration(userOptions: UserOptions): AstroIntegration {
|
||||||
if (!userOptions?.mode) {
|
if (!userOptions?.mode) {
|
||||||
throw new Error(`[@astrojs/node] Setting the 'mode' option is required.`);
|
throw new AstroError(`Setting the 'mode' option is required.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let _options: Options;
|
let _options: Options;
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { fileURLToPath } from 'node:url';
|
||||||
import { getNetworkAddress } from './get-network-address.js';
|
import { getNetworkAddress } from './get-network-address.js';
|
||||||
import { createServer } from './http-server.js';
|
import { createServer } from './http-server.js';
|
||||||
import type { createExports } from './server';
|
import type { createExports } from './server';
|
||||||
|
import { AstroError } from 'astro/errors';
|
||||||
|
|
||||||
const preview: CreatePreviewServer = async function ({
|
const preview: CreatePreviewServer = async function ({
|
||||||
client,
|
client,
|
||||||
|
@ -11,6 +12,7 @@ const preview: CreatePreviewServer = async function ({
|
||||||
host,
|
host,
|
||||||
port,
|
port,
|
||||||
base,
|
base,
|
||||||
|
logger,
|
||||||
}) {
|
}) {
|
||||||
type ServerModule = ReturnType<typeof createExports>;
|
type ServerModule = ReturnType<typeof createExports>;
|
||||||
type MaybeServerModule = Partial<ServerModule>;
|
type MaybeServerModule = Partial<ServerModule>;
|
||||||
|
@ -21,13 +23,13 @@ const preview: CreatePreviewServer = async function ({
|
||||||
if (typeof ssrModule.handler === 'function') {
|
if (typeof ssrModule.handler === 'function') {
|
||||||
ssrHandler = ssrModule.handler;
|
ssrHandler = ssrModule.handler;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new AstroError(
|
||||||
`The server entrypoint doesn't have a handler. Are you sure this is the right file?`
|
`The server entrypoint doesn't have a handler. Are you sure this is the right file?`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if ((err as any).code === 'ERR_MODULE_NOT_FOUND') {
|
if ((err as any).code === 'ERR_MODULE_NOT_FOUND') {
|
||||||
throw new Error(
|
throw new AstroError(
|
||||||
`The server entrypoint ${fileURLToPath(
|
`The server entrypoint ${fileURLToPath(
|
||||||
serverEntrypoint
|
serverEntrypoint
|
||||||
)} does not exist. Have you ran a build yet?`
|
)} does not exist. Have you ran a build yet?`
|
||||||
|
@ -63,13 +65,11 @@ const preview: CreatePreviewServer = async function ({
|
||||||
const address = getNetworkAddress('http', host, port);
|
const address = getNetworkAddress('http', host, port);
|
||||||
|
|
||||||
if (host === undefined) {
|
if (host === undefined) {
|
||||||
// eslint-disable-next-line no-console
|
logger.info(
|
||||||
console.log(
|
|
||||||
`Preview server listening on \n local: ${address.local[0]} \t\n network: ${address.network[0]}\n`
|
`Preview server listening on \n local: ${address.local[0]} \t\n network: ${address.network[0]}\n`
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// eslint-disable-next-line no-console
|
logger.info(`Preview server listening on ${address.local[0]}`);
|
||||||
console.log(`Preview server listening on ${address.local[0]}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return server;
|
return server;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
import type { ReadableStreamDefaultReadResult } from 'node:stream/web';
|
import type { ReadableStreamDefaultReadResult } from 'node:stream/web';
|
||||||
import { Readable as NodeReadableStream } from 'stream';
|
import { Readable as NodeReadableStream } from 'stream';
|
||||||
|
import { AstroError } from 'astro/errors';
|
||||||
|
|
||||||
interface NodeStreamIterator<T> {
|
interface NodeStreamIterator<T> {
|
||||||
next(): Promise<IteratorResult<T, boolean | undefined>>;
|
next(): Promise<IteratorResult<T, boolean | undefined>>;
|
||||||
|
@ -221,5 +222,7 @@ export function responseIterator<T>(response: Response | Buffer): AsyncIterableI
|
||||||
|
|
||||||
if (isNodeReadableStream(body)) return nodeStreamIterator<T>(body);
|
if (isNodeReadableStream(body)) return nodeStreamIterator<T>(body);
|
||||||
|
|
||||||
throw new Error('Unknown body type for responseIterator. Please pass a streamable response.');
|
throw new AstroError(
|
||||||
|
'Unknown body type for responseIterator. Please pass a streamable response.'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ export function getResolvedHostForHttpServer(host: string | boolean) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function startServer(app: NodeApp, options: Options) {
|
export default function startServer(app: NodeApp, options: Options) {
|
||||||
|
const logger = app.getAdapterLogger();
|
||||||
const port = process.env.PORT ? Number(process.env.PORT) : options.port ?? 8080;
|
const port = process.env.PORT ? Number(process.env.PORT) : options.port ?? 8080;
|
||||||
const { client } = resolvePaths(options);
|
const { client } = resolvePaths(options);
|
||||||
const handler = middleware(app, options.mode);
|
const handler = middleware(app, options.mode);
|
||||||
|
@ -59,13 +60,11 @@ export default function startServer(app: NodeApp, options: Options) {
|
||||||
const address = getNetworkAddress(protocol, host, port);
|
const address = getNetworkAddress(protocol, host, port);
|
||||||
|
|
||||||
if (host === undefined) {
|
if (host === undefined) {
|
||||||
// eslint-disable-next-line no-console
|
logger.info(
|
||||||
console.log(
|
`Server listening on \n local: ${address.local[0]} \t\n network: ${address.network[0]}\n`
|
||||||
`Preview server listening on \n local: ${address.local[0]} \t\n network: ${address.network[0]}\n`
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// eslint-disable-next-line no-console
|
logger.info(`Server listening on ${address.local[0]}`);
|
||||||
console.log(`Preview server listening on ${address.local[0]}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import type { AstroAdapter, AstroConfig, AstroIntegration, RouteData } from 'astro';
|
import type { AstroAdapter, AstroConfig, AstroIntegration, RouteData } from 'astro';
|
||||||
|
import { AstroError } from 'astro/errors';
|
||||||
import glob from 'fast-glob';
|
import glob from 'fast-glob';
|
||||||
import { basename } from 'node:path';
|
import { basename } from 'node:path';
|
||||||
import { fileURLToPath, pathToFileURL } from 'node:url';
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
||||||
|
@ -136,10 +136,9 @@ export default function vercelServerless({
|
||||||
serverEntry = config.build.serverEntry;
|
serverEntry = config.build.serverEntry;
|
||||||
|
|
||||||
if (config.output === 'static') {
|
if (config.output === 'static') {
|
||||||
throw new Error(`
|
throw new AstroError(
|
||||||
[@astrojs/vercel] \`output: "server"\` or \`output: "hybrid"\` is required to use the serverless adapter.
|
'`output: "server"` or `output: "hybrid"` is required to use the serverless adapter.'
|
||||||
|
);
|
||||||
`);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue