[ci] format
This commit is contained in:
parent
c77a6cbe34
commit
63a3282f81
29 changed files with 241 additions and 240 deletions
|
@ -5,8 +5,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export type EventMap = {
|
export type EventMap = {
|
||||||
[key: string]: (...args: any[]) => void
|
[key: string]: (...args: any[]) => void;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type-safe event emitter.
|
* Type-safe event emitter.
|
||||||
|
@ -25,25 +25,25 @@ export type EventMap = {
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
interface TypedEventEmitter<Events extends EventMap> {
|
interface TypedEventEmitter<Events extends EventMap> {
|
||||||
addListener<E extends keyof Events> (event: E, listener: Events[E]): this
|
addListener<E extends keyof Events>(event: E, listener: Events[E]): this;
|
||||||
on<E extends keyof Events> (event: E, listener: Events[E]): this
|
on<E extends keyof Events>(event: E, listener: Events[E]): this;
|
||||||
once<E extends keyof Events> (event: E, listener: Events[E]): this
|
once<E extends keyof Events>(event: E, listener: Events[E]): this;
|
||||||
prependListener<E extends keyof Events> (event: E, listener: Events[E]): this
|
prependListener<E extends keyof Events>(event: E, listener: Events[E]): this;
|
||||||
prependOnceListener<E extends keyof Events> (event: E, listener: Events[E]): this
|
prependOnceListener<E extends keyof Events>(event: E, listener: Events[E]): this;
|
||||||
|
|
||||||
off<E extends keyof Events>(event: E, listener: Events[E]): this
|
off<E extends keyof Events>(event: E, listener: Events[E]): this;
|
||||||
removeAllListeners<E extends keyof Events> (event?: E): this
|
removeAllListeners<E extends keyof Events>(event?: E): this;
|
||||||
removeListener<E extends keyof Events> (event: E, listener: Events[E]): this
|
removeListener<E extends keyof Events>(event: E, listener: Events[E]): this;
|
||||||
|
|
||||||
emit<E extends keyof Events> (event: E, ...args: Parameters<Events[E]>): boolean
|
emit<E extends keyof Events>(event: E, ...args: Parameters<Events[E]>): boolean;
|
||||||
// The sloppy `eventNames()` return type is to mitigate type incompatibilities - see #5
|
// The sloppy `eventNames()` return type is to mitigate type incompatibilities - see #5
|
||||||
eventNames (): (keyof Events | string | symbol)[]
|
eventNames(): (keyof Events | string | symbol)[];
|
||||||
rawListeners<E extends keyof Events> (event: E): Events[E][]
|
rawListeners<E extends keyof Events>(event: E): Events[E][];
|
||||||
listeners<E extends keyof Events> (event: E): Events[E][]
|
listeners<E extends keyof Events>(event: E): Events[E][];
|
||||||
listenerCount<E extends keyof Events> (event: E): number
|
listenerCount<E extends keyof Events>(event: E): number;
|
||||||
|
|
||||||
getMaxListeners (): number
|
getMaxListeners(): number;
|
||||||
setMaxListeners (maxListeners: number): this
|
setMaxListeners(maxListeners: number): this;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TypedEventEmitter
|
export default TypedEventEmitter;
|
||||||
|
|
|
@ -190,12 +190,7 @@ export async function openConfig(configOptions: LoadConfigOptions): Promise<Open
|
||||||
if (config) {
|
if (config) {
|
||||||
userConfig = config.value;
|
userConfig = config.value;
|
||||||
}
|
}
|
||||||
const astroConfig = await resolveConfig(
|
const astroConfig = await resolveConfig(userConfig, root, flags, configOptions.cmd);
|
||||||
userConfig,
|
|
||||||
root,
|
|
||||||
flags,
|
|
||||||
configOptions.cmd
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
astroConfig,
|
astroConfig,
|
||||||
|
@ -318,7 +313,7 @@ export async function resolveConfig(
|
||||||
|
|
||||||
export function createDefaultDevConfig(
|
export function createDefaultDevConfig(
|
||||||
userConfig: AstroUserConfig = {},
|
userConfig: AstroUserConfig = {},
|
||||||
root: string = process.cwd(),
|
root: string = process.cwd()
|
||||||
) {
|
) {
|
||||||
return resolveConfig(userConfig, root, undefined, 'dev');
|
return resolveConfig(userConfig, root, undefined, 'dev');
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,5 +7,5 @@ export {
|
||||||
validateConfig,
|
validateConfig,
|
||||||
} from './config.js';
|
} from './config.js';
|
||||||
export type { AstroConfigSchema } from './schema';
|
export type { AstroConfigSchema } from './schema';
|
||||||
export { createSettings, createDefaultDevSettings } from './settings.js';
|
export { createDefaultDevSettings, createSettings } from './settings.js';
|
||||||
export { loadTSConfig, updateTSConfigForFramework } from './tsconfig.js';
|
export { loadTSConfig, updateTSConfigForFramework } from './tsconfig.js';
|
||||||
|
|
|
@ -2,8 +2,8 @@ import type { AstroConfig, AstroSettings, AstroUserConfig } from '../../@types/a
|
||||||
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './../constants.js';
|
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './../constants.js';
|
||||||
|
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import { createDefaultDevConfig } from './config.js';
|
|
||||||
import jsxRenderer from '../../jsx/renderer.js';
|
import jsxRenderer from '../../jsx/renderer.js';
|
||||||
|
import { createDefaultDevConfig } from './config.js';
|
||||||
import { loadTSConfig } from './tsconfig.js';
|
import { loadTSConfig } from './tsconfig.js';
|
||||||
|
|
||||||
export function createBaseSettings(config: AstroConfig): AstroSettings {
|
export function createBaseSettings(config: AstroConfig): AstroSettings {
|
||||||
|
@ -34,10 +34,9 @@ export async function createDefaultDevSettings(
|
||||||
userConfig: AstroUserConfig = {},
|
userConfig: AstroUserConfig = {},
|
||||||
root?: string | URL
|
root?: string | URL
|
||||||
): Promise<AstroSettings> {
|
): Promise<AstroSettings> {
|
||||||
if(root && typeof root !== 'string') {
|
if (root && typeof root !== 'string') {
|
||||||
root = fileURLToPath(root);
|
root = fileURLToPath(root);
|
||||||
}
|
}
|
||||||
const config = await createDefaultDevConfig(userConfig, root);
|
const config = await createDefaultDevConfig(userConfig, root);
|
||||||
return createBaseSettings(config);
|
return createBaseSettings(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,12 @@ import envVitePlugin from '../vite-plugin-env/index.js';
|
||||||
import htmlVitePlugin from '../vite-plugin-html/index.js';
|
import htmlVitePlugin from '../vite-plugin-html/index.js';
|
||||||
import astroIntegrationsContainerPlugin from '../vite-plugin-integrations-container/index.js';
|
import astroIntegrationsContainerPlugin from '../vite-plugin-integrations-container/index.js';
|
||||||
import jsxVitePlugin from '../vite-plugin-jsx/index.js';
|
import jsxVitePlugin from '../vite-plugin-jsx/index.js';
|
||||||
|
import astroLoadFallbackPlugin from '../vite-plugin-load-fallback/index.js';
|
||||||
import legacyMarkdownVitePlugin from '../vite-plugin-markdown-legacy/index.js';
|
import legacyMarkdownVitePlugin from '../vite-plugin-markdown-legacy/index.js';
|
||||||
import markdownVitePlugin from '../vite-plugin-markdown/index.js';
|
import markdownVitePlugin from '../vite-plugin-markdown/index.js';
|
||||||
import astroScriptsPlugin from '../vite-plugin-scripts/index.js';
|
import astroScriptsPlugin from '../vite-plugin-scripts/index.js';
|
||||||
import astroScriptsPageSSRPlugin from '../vite-plugin-scripts/page-ssr.js';
|
import astroScriptsPageSSRPlugin from '../vite-plugin-scripts/page-ssr.js';
|
||||||
import { createCustomViteLogger } from './errors/dev/index.js';
|
import { createCustomViteLogger } from './errors/dev/index.js';
|
||||||
import astroLoadFallbackPlugin from '../vite-plugin-load-fallback/index.js';
|
|
||||||
import { resolveDependency } from './util.js';
|
import { resolveDependency } from './util.js';
|
||||||
|
|
||||||
interface CreateViteOptions {
|
interface CreateViteOptions {
|
||||||
|
@ -110,7 +110,7 @@ export async function createVite(
|
||||||
astroPostprocessVitePlugin({ settings }),
|
astroPostprocessVitePlugin({ settings }),
|
||||||
astroIntegrationsContainerPlugin({ settings, logging }),
|
astroIntegrationsContainerPlugin({ settings, logging }),
|
||||||
astroScriptsPageSSRPlugin({ settings }),
|
astroScriptsPageSSRPlugin({ settings }),
|
||||||
astroLoadFallbackPlugin({ fs })
|
astroLoadFallbackPlugin({ fs }),
|
||||||
],
|
],
|
||||||
publicDir: fileURLToPath(settings.config.publicDir),
|
publicDir: fileURLToPath(settings.config.publicDir),
|
||||||
root: fileURLToPath(settings.config.root),
|
root: fileURLToPath(settings.config.root),
|
||||||
|
|
|
@ -1,23 +1,21 @@
|
||||||
|
import * as http from 'http';
|
||||||
import type { AddressInfo } from 'net';
|
import type { AddressInfo } from 'net';
|
||||||
import type { AstroSettings, AstroUserConfig } from '../../@types/astro';
|
import type { AstroSettings, AstroUserConfig } from '../../@types/astro';
|
||||||
import * as http from 'http';
|
|
||||||
|
|
||||||
|
import nodeFs from 'fs';
|
||||||
|
import * as vite from 'vite';
|
||||||
import {
|
import {
|
||||||
runHookConfigDone,
|
runHookConfigDone,
|
||||||
runHookConfigSetup,
|
runHookConfigSetup,
|
||||||
runHookServerSetup,
|
runHookServerSetup,
|
||||||
runHookServerStart,
|
runHookServerStart,
|
||||||
} from '../../integrations/index.js';
|
} from '../../integrations/index.js';
|
||||||
import { createVite } from '../create-vite.js';
|
|
||||||
import { LogOptions } from '../logger/core.js';
|
|
||||||
import { nodeLogDestination } from '../logger/node.js';
|
|
||||||
import nodeFs from 'fs';
|
|
||||||
import * as vite from 'vite';
|
|
||||||
import { createDefaultDevSettings } from '../config/index.js';
|
import { createDefaultDevSettings } from '../config/index.js';
|
||||||
|
import { createVite } from '../create-vite.js';
|
||||||
|
import { LogOptions } from '../logger/core.js';
|
||||||
|
import { nodeLogDestination } from '../logger/node.js';
|
||||||
import { apply as applyPolyfill } from '../polyfill.js';
|
import { apply as applyPolyfill } from '../polyfill.js';
|
||||||
|
|
||||||
|
|
||||||
const defaultLogging: LogOptions = {
|
const defaultLogging: LogOptions = {
|
||||||
dest: nodeLogDestination,
|
dest: nodeLogDestination,
|
||||||
level: 'error',
|
level: 'error',
|
||||||
|
@ -47,7 +45,7 @@ export async function createContainer(params: CreateContainerParams = {}): Promi
|
||||||
isRestart = false,
|
isRestart = false,
|
||||||
logging = defaultLogging,
|
logging = defaultLogging,
|
||||||
settings = await createDefaultDevSettings(params.userConfig, params.root),
|
settings = await createDefaultDevSettings(params.userConfig, params.root),
|
||||||
fs = nodeFs
|
fs = nodeFs,
|
||||||
} = params;
|
} = params;
|
||||||
|
|
||||||
// Initialize
|
// Initialize
|
||||||
|
@ -97,11 +95,15 @@ export async function createContainer(params: CreateContainerParams = {}): Promi
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
return viteServer.close();
|
return viteServer.close();
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function startContainer({ settings, viteServer, logging }: Container): Promise<AddressInfo> {
|
export async function startContainer({
|
||||||
|
settings,
|
||||||
|
viteServer,
|
||||||
|
logging,
|
||||||
|
}: Container): Promise<AddressInfo> {
|
||||||
const { port } = settings.config.server;
|
const { port } = settings.config.server;
|
||||||
await viteServer.listen(port);
|
await viteServer.listen(port);
|
||||||
const devServerAddressInfo = viteServer.httpServer!.address() as AddressInfo;
|
const devServerAddressInfo = viteServer.httpServer!.address() as AddressInfo;
|
||||||
|
@ -114,7 +116,10 @@ export async function startContainer({ settings, viteServer, logging }: Containe
|
||||||
return devServerAddressInfo;
|
return devServerAddressInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function runInContainer(params: CreateContainerParams, callback: (container: Container) => Promise<void> | void) {
|
export async function runInContainer(
|
||||||
|
params: CreateContainerParams,
|
||||||
|
callback: (container: Container) => Promise<void> | void
|
||||||
|
) {
|
||||||
const container = await createContainer(params);
|
const container = await createContainer(params);
|
||||||
try {
|
try {
|
||||||
await callback(container);
|
await callback(container);
|
||||||
|
|
|
@ -1,9 +1,2 @@
|
||||||
export {
|
export { createContainer, runInContainer, startContainer } from './container.js';
|
||||||
createContainer,
|
export { default } from './dev.js';
|
||||||
startContainer,
|
|
||||||
runInContainer
|
|
||||||
} from './container.js';
|
|
||||||
|
|
||||||
export {
|
|
||||||
default
|
|
||||||
} from './dev.js';
|
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
import type { ModuleLoader } from '../../module-loader/index.js';
|
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import {
|
import { createLogger, type ErrorPayload, type Logger, type LogLevel } from 'vite';
|
||||||
createLogger,
|
import type { ModuleLoader } from '../../module-loader/index.js';
|
||||||
type ErrorPayload,
|
|
||||||
type Logger,
|
|
||||||
type LogLevel,
|
|
||||||
} from 'vite';
|
|
||||||
import { AstroErrorCodes } from '../codes.js';
|
import { AstroErrorCodes } from '../codes.js';
|
||||||
import { AstroError, type ErrorWithMetadata } from '../errors.js';
|
import { AstroError, type ErrorWithMetadata } from '../errors.js';
|
||||||
import { incompatPackageExp } from './utils.js';
|
import { incompatPackageExp } from './utils.js';
|
||||||
|
@ -30,7 +25,7 @@ export function createCustomViteLogger(logLevel: LogLevel): Logger {
|
||||||
export function enhanceViteSSRError(
|
export function enhanceViteSSRError(
|
||||||
error: Error,
|
error: Error,
|
||||||
filePath?: URL,
|
filePath?: URL,
|
||||||
loader?: ModuleLoader,
|
loader?: ModuleLoader
|
||||||
): AstroError {
|
): AstroError {
|
||||||
// Vite will give you better stacktraces, using sourcemaps.
|
// Vite will give you better stacktraces, using sourcemaps.
|
||||||
if (loader) {
|
if (loader) {
|
||||||
|
|
|
@ -1,14 +1,3 @@
|
||||||
export type {
|
export { createLoader } from './loader.js';
|
||||||
ModuleInfo,
|
export type { LoaderEvents, ModuleInfo, ModuleLoader, ModuleNode } from './loader.js';
|
||||||
ModuleLoader,
|
export { createViteLoader } from './vite.js';
|
||||||
ModuleNode,
|
|
||||||
LoaderEvents
|
|
||||||
} from './loader.js';
|
|
||||||
|
|
||||||
export {
|
|
||||||
createLoader
|
|
||||||
} from './loader.js';
|
|
||||||
|
|
||||||
export {
|
|
||||||
createViteLoader
|
|
||||||
} from './vite.js';
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type TypedEmitter from '../../@types/typed-emitter';
|
|
||||||
import type * as fs from 'fs';
|
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
|
import type * as fs from 'fs';
|
||||||
|
import type TypedEmitter from '../../@types/typed-emitter';
|
||||||
|
|
||||||
// This is a generic interface for a module loader. In the astro cli this is
|
// This is a generic interface for a module loader. In the astro cli this is
|
||||||
// fulfilled by Vite, see vite.ts
|
// fulfilled by Vite, see vite.ts
|
||||||
|
@ -10,10 +10,10 @@ export type LoaderEvents = {
|
||||||
'file-change': (msg: [path: string, stats?: fs.Stats | undefined]) => void;
|
'file-change': (msg: [path: string, stats?: fs.Stats | undefined]) => void;
|
||||||
'file-unlink': (msg: [path: string, stats?: fs.Stats | undefined]) => void;
|
'file-unlink': (msg: [path: string, stats?: fs.Stats | undefined]) => void;
|
||||||
'hmr-error': (msg: {
|
'hmr-error': (msg: {
|
||||||
type: 'error',
|
type: 'error';
|
||||||
err: {
|
err: {
|
||||||
message: string;
|
message: string;
|
||||||
stack: string
|
stack: string;
|
||||||
};
|
};
|
||||||
}) => void;
|
}) => void;
|
||||||
};
|
};
|
||||||
|
@ -53,19 +53,33 @@ export interface ModuleInfo {
|
||||||
|
|
||||||
export function createLoader(overrides: Partial<ModuleLoader>): ModuleLoader {
|
export function createLoader(overrides: Partial<ModuleLoader>): ModuleLoader {
|
||||||
return {
|
return {
|
||||||
import() { throw new Error(`Not implemented`); },
|
import() {
|
||||||
resolveId(id) { return Promise.resolve(id); },
|
throw new Error(`Not implemented`);
|
||||||
getModuleById() {return undefined },
|
},
|
||||||
getModulesByFile() { return undefined },
|
resolveId(id) {
|
||||||
getModuleInfo() { return null; },
|
return Promise.resolve(id);
|
||||||
eachModule() { throw new Error(`Not implemented`); },
|
},
|
||||||
|
getModuleById() {
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
getModulesByFile() {
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
getModuleInfo() {
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
eachModule() {
|
||||||
|
throw new Error(`Not implemented`);
|
||||||
|
},
|
||||||
invalidateModule() {},
|
invalidateModule() {},
|
||||||
fixStacktrace() {},
|
fixStacktrace() {},
|
||||||
clientReload() {},
|
clientReload() {},
|
||||||
webSocketSend() {},
|
webSocketSend() {},
|
||||||
isHttps() { return true; },
|
isHttps() {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
events: new EventEmitter() as ModuleLoaderEventEmitter,
|
events: new EventEmitter() as ModuleLoaderEventEmitter,
|
||||||
|
|
||||||
...overrides
|
...overrides,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
import { EventEmitter } from 'events';
|
||||||
import type * as vite from 'vite';
|
import type * as vite from 'vite';
|
||||||
import type { ModuleLoader, ModuleLoaderEventEmitter } from './loader';
|
import type { ModuleLoader, ModuleLoaderEventEmitter } from './loader';
|
||||||
import { EventEmitter } from 'events';
|
|
||||||
|
|
||||||
export function createViteLoader(viteServer: vite.ViteDevServer): ModuleLoader {
|
export function createViteLoader(viteServer: vite.ViteDevServer): ModuleLoader {
|
||||||
const events = new EventEmitter() as ModuleLoaderEventEmitter;
|
const events = new EventEmitter() as ModuleLoaderEventEmitter;
|
||||||
|
@ -9,8 +9,8 @@ export function createViteLoader(viteServer: vite.ViteDevServer): ModuleLoader {
|
||||||
viteServer.watcher.on('unlink', (...args) => events.emit('file-unlink', args));
|
viteServer.watcher.on('unlink', (...args) => events.emit('file-unlink', args));
|
||||||
viteServer.watcher.on('change', (...args) => events.emit('file-change', args));
|
viteServer.watcher.on('change', (...args) => events.emit('file-change', args));
|
||||||
|
|
||||||
wrapMethod(viteServer.ws, 'send', msg => {
|
wrapMethod(viteServer.ws, 'send', (msg) => {
|
||||||
if(msg?.type === 'error') {
|
if (msg?.type === 'error') {
|
||||||
events.emit('hmr-error', msg);
|
events.emit('hmr-error', msg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -33,18 +33,18 @@ export function createViteLoader(viteServer: vite.ViteDevServer): ModuleLoader {
|
||||||
return viteServer.pluginContainer.getModuleInfo(id);
|
return viteServer.pluginContainer.getModuleInfo(id);
|
||||||
},
|
},
|
||||||
eachModule(cb) {
|
eachModule(cb) {
|
||||||
return viteServer.moduleGraph.idToModuleMap.forEach(cb);
|
return viteServer.moduleGraph.idToModuleMap.forEach(cb);
|
||||||
},
|
},
|
||||||
invalidateModule(mod) {
|
invalidateModule(mod) {
|
||||||
viteServer.moduleGraph.invalidateModule(mod as vite.ModuleNode);
|
viteServer.moduleGraph.invalidateModule(mod as vite.ModuleNode);
|
||||||
},
|
},
|
||||||
fixStacktrace(err) {
|
fixStacktrace(err) {
|
||||||
return viteServer.ssrFixStacktrace(err);
|
return viteServer.ssrFixStacktrace(err);
|
||||||
},
|
},
|
||||||
clientReload() {
|
clientReload() {
|
||||||
viteServer.ws.send({
|
viteServer.ws.send({
|
||||||
type: 'full-reload',
|
type: 'full-reload',
|
||||||
path: '*'
|
path: '*',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
webSocketSend(msg) {
|
webSocketSend(msg) {
|
||||||
|
@ -53,14 +53,13 @@ export function createViteLoader(viteServer: vite.ViteDevServer): ModuleLoader {
|
||||||
isHttps() {
|
isHttps() {
|
||||||
return !!viteServer.config.server.https;
|
return !!viteServer.config.server.https;
|
||||||
},
|
},
|
||||||
events
|
events,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function wrapMethod(object: any, method: string, newFn: (...args: any[]) => void) {
|
function wrapMethod(object: any, method: string, newFn: (...args: any[]) => void) {
|
||||||
const orig = object[method];
|
const orig = object[method];
|
||||||
object[method] = function(...args: any[]) {
|
object[method] = function (...args: any[]) {
|
||||||
newFn.apply(this, args);
|
newFn.apply(this, args);
|
||||||
return orig.apply(this, args);
|
return orig.apply(this, args);
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,8 +19,7 @@ export async function getStylesForURL(
|
||||||
const ext = path.extname(importedModule.url).toLowerCase();
|
const ext = path.extname(importedModule.url).toLowerCase();
|
||||||
if (STYLE_EXTENSIONS.has(ext)) {
|
if (STYLE_EXTENSIONS.has(ext)) {
|
||||||
// The SSR module is possibly not loaded. Load it if it's null.
|
// The SSR module is possibly not loaded. Load it if it's null.
|
||||||
const ssrModule =
|
const ssrModule = importedModule.ssrModule ?? (await loader.import(importedModule.url));
|
||||||
importedModule.ssrModule ?? (await loader.import(importedModule.url));
|
|
||||||
if (
|
if (
|
||||||
mode === 'development' && // only inline in development
|
mode === 'development' && // only inline in development
|
||||||
typeof ssrModule?.default === 'string' // ignore JS module styles
|
typeof ssrModule?.default === 'string' // ignore JS module styles
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import type { ViteDevServer } from 'vite';
|
|
||||||
import type { AstroSettings, RuntimeMode } from '../../../@types/astro';
|
import type { AstroSettings, RuntimeMode } from '../../../@types/astro';
|
||||||
import type { LogOptions } from '../../logger/core.js';
|
import type { LogOptions } from '../../logger/core.js';
|
||||||
import type { Environment } from '../index';
|
|
||||||
import type { ModuleLoader } from '../../module-loader/index';
|
import type { ModuleLoader } from '../../module-loader/index';
|
||||||
|
import type { Environment } from '../index';
|
||||||
|
|
||||||
import { createEnvironment } from '../index.js';
|
import { createEnvironment } from '../index.js';
|
||||||
import { RouteCache } from '../route-cache.js';
|
import { RouteCache } from '../route-cache.js';
|
||||||
|
|
|
@ -7,11 +7,11 @@ import type {
|
||||||
SSRElement,
|
SSRElement,
|
||||||
SSRLoadedRenderer,
|
SSRLoadedRenderer,
|
||||||
} from '../../../@types/astro';
|
} from '../../../@types/astro';
|
||||||
import type { ModuleLoader } from '../../module-loader/index';
|
|
||||||
import { PAGE_SCRIPT_ID } from '../../../vite-plugin-scripts/index.js';
|
import { PAGE_SCRIPT_ID } from '../../../vite-plugin-scripts/index.js';
|
||||||
import { enhanceViteSSRError } from '../../errors/dev/index.js';
|
import { enhanceViteSSRError } from '../../errors/dev/index.js';
|
||||||
import { AggregateError, CSSError, MarkdownError } from '../../errors/index.js';
|
import { AggregateError, CSSError, MarkdownError } from '../../errors/index.js';
|
||||||
import { LogOptions } from '../../logger/core.js';
|
import { LogOptions } from '../../logger/core.js';
|
||||||
|
import type { ModuleLoader } from '../../module-loader/index';
|
||||||
import { isPage, resolveIdToUrl } from '../../util.js';
|
import { isPage, resolveIdToUrl } from '../../util.js';
|
||||||
import { createRenderContext, renderPage as coreRenderPage } from '../index.js';
|
import { createRenderContext, renderPage as coreRenderPage } from '../index.js';
|
||||||
import { filterFoundRenderers, loadRenderer } from '../renderer.js';
|
import { filterFoundRenderers, loadRenderer } from '../renderer.js';
|
||||||
|
|
|
@ -224,7 +224,12 @@ export function createRouteManifest(
|
||||||
const validEndpointExtensions: Set<string> = new Set(['.js', '.ts']);
|
const validEndpointExtensions: Set<string> = new Set(['.js', '.ts']);
|
||||||
const localFs = fsMod ?? nodeFs;
|
const localFs = fsMod ?? nodeFs;
|
||||||
|
|
||||||
function walk(fs: typeof nodeFs, dir: string, parentSegments: RoutePart[][], parentParams: string[]) {
|
function walk(
|
||||||
|
fs: typeof nodeFs,
|
||||||
|
dir: string,
|
||||||
|
parentSegments: RoutePart[][],
|
||||||
|
parentParams: string[]
|
||||||
|
) {
|
||||||
let items: Item[] = [];
|
let items: Item[] = [];
|
||||||
fs.readdirSync(dir).forEach((basename) => {
|
fs.readdirSync(dir).forEach((basename) => {
|
||||||
const resolved = path.join(dir, basename);
|
const resolved = path.join(dir, basename);
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import type { ModuleLoader } from './module-loader';
|
|
||||||
import eol from 'eol';
|
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import resolve from 'resolve';
|
import resolve from 'resolve';
|
||||||
|
@ -8,6 +6,7 @@ import { fileURLToPath, pathToFileURL } from 'url';
|
||||||
import { normalizePath } from 'vite';
|
import { normalizePath } from 'vite';
|
||||||
import type { AstroConfig, AstroSettings, RouteType } from '../@types/astro';
|
import type { AstroConfig, AstroSettings, RouteType } from '../@types/astro';
|
||||||
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './constants.js';
|
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './constants.js';
|
||||||
|
import type { ModuleLoader } from './module-loader';
|
||||||
import { prependForwardSlash, removeTrailingForwardSlash } from './path.js';
|
import { prependForwardSlash, removeTrailingForwardSlash } from './path.js';
|
||||||
|
|
||||||
/** Returns true if argument is an object of any prototype/class (but not null). */
|
/** Returns true if argument is an object of any prototype/class (but not null). */
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
import type { ServerState } from './server-state';
|
|
||||||
import type { LoaderEvents, ModuleLoader } from '../core/module-loader/index';
|
import type { LoaderEvents, ModuleLoader } from '../core/module-loader/index';
|
||||||
|
import type { ServerState } from './server-state';
|
||||||
|
|
||||||
import { createServerState, setRouteError, setServerError, clearRouteError } from './server-state.js';
|
import {
|
||||||
|
clearRouteError,
|
||||||
|
createServerState,
|
||||||
|
setRouteError,
|
||||||
|
setServerError,
|
||||||
|
} from './server-state.js';
|
||||||
|
|
||||||
type ReloadFn = () => void;
|
type ReloadFn = () => void;
|
||||||
|
|
||||||
|
@ -11,14 +16,16 @@ export interface DevServerController {
|
||||||
onHMRError: LoaderEvents['hmr-error'];
|
onHMRError: LoaderEvents['hmr-error'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CreateControllerParams = {
|
export type CreateControllerParams =
|
||||||
loader: ModuleLoader;
|
| {
|
||||||
} | {
|
loader: ModuleLoader;
|
||||||
reload: ReloadFn;
|
}
|
||||||
};
|
| {
|
||||||
|
reload: ReloadFn;
|
||||||
|
};
|
||||||
|
|
||||||
export function createController(params: CreateControllerParams): DevServerController {
|
export function createController(params: CreateControllerParams): DevServerController {
|
||||||
if('loader' in params) {
|
if ('loader' in params) {
|
||||||
return createLoaderController(params.loader);
|
return createLoaderController(params.loader);
|
||||||
} else {
|
} else {
|
||||||
return createBaseController(params);
|
return createBaseController(params);
|
||||||
|
@ -29,7 +36,7 @@ export function createBaseController({ reload }: { reload: ReloadFn }): DevServe
|
||||||
const serverState = createServerState();
|
const serverState = createServerState();
|
||||||
|
|
||||||
const onFileChange: LoaderEvents['file-change'] = () => {
|
const onFileChange: LoaderEvents['file-change'] = () => {
|
||||||
if(serverState.state === 'error') {
|
if (serverState.state === 'error') {
|
||||||
reload();
|
reload();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -39,7 +46,7 @@ export function createBaseController({ reload }: { reload: ReloadFn }): DevServe
|
||||||
let stack = payload?.err?.stack ?? 'Unknown stack';
|
let stack = payload?.err?.stack ?? 'Unknown stack';
|
||||||
let error = new Error(msg);
|
let error = new Error(msg);
|
||||||
Object.defineProperty(error, 'stack', {
|
Object.defineProperty(error, 'stack', {
|
||||||
value: stack
|
value: stack,
|
||||||
});
|
});
|
||||||
setServerError(serverState, error);
|
setServerError(serverState, error);
|
||||||
};
|
};
|
||||||
|
@ -47,7 +54,7 @@ export function createBaseController({ reload }: { reload: ReloadFn }): DevServe
|
||||||
return {
|
return {
|
||||||
state: serverState,
|
state: serverState,
|
||||||
onFileChange,
|
onFileChange,
|
||||||
onHMRError
|
onHMRError,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,21 +62,21 @@ export function createLoaderController(loader: ModuleLoader): DevServerControlle
|
||||||
const controller = createBaseController({
|
const controller = createBaseController({
|
||||||
reload() {
|
reload() {
|
||||||
loader.clientReload();
|
loader.clientReload();
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const baseOnFileChange = controller.onFileChange;
|
const baseOnFileChange = controller.onFileChange;
|
||||||
controller.onFileChange = (...args) => {
|
controller.onFileChange = (...args) => {
|
||||||
if(controller.state.state === 'error') {
|
if (controller.state.state === 'error') {
|
||||||
// If we are in an error state, check if there are any modules with errors
|
// If we are in an error state, check if there are any modules with errors
|
||||||
// and if so invalidate them so that they will be updated on refresh.
|
// and if so invalidate them so that they will be updated on refresh.
|
||||||
loader.eachModule(mod => {
|
loader.eachModule((mod) => {
|
||||||
if(mod.ssrError) {
|
if (mod.ssrError) {
|
||||||
loader.invalidateModule(mod);
|
loader.invalidateModule(mod);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
baseOnFileChange(...args);
|
baseOnFileChange(...args);
|
||||||
}
|
};
|
||||||
|
|
||||||
loader.events.on('file-change', controller.onFileChange);
|
loader.events.on('file-change', controller.onFileChange);
|
||||||
loader.events.on('hmr-error', controller.onHMRError);
|
loader.events.on('hmr-error', controller.onHMRError);
|
||||||
|
@ -88,12 +95,12 @@ export async function runWithErrorHandling({
|
||||||
controller: { state },
|
controller: { state },
|
||||||
pathname,
|
pathname,
|
||||||
run,
|
run,
|
||||||
onError
|
onError,
|
||||||
}: RunWithErrorHandlingParams) {
|
}: RunWithErrorHandlingParams) {
|
||||||
try {
|
try {
|
||||||
await run();
|
await run();
|
||||||
clearRouteError(state, pathname);
|
clearRouteError(state, pathname);
|
||||||
} catch(err) {
|
} catch (err) {
|
||||||
const error = onError(err);
|
const error = onError(err);
|
||||||
setRouteError(state, pathname, error);
|
setRouteError(state, pathname, error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,3 @@
|
||||||
export {
|
export { createController, runWithErrorHandling } from './controller.js';
|
||||||
createController,
|
export { default as vitePluginAstroServer } from './plugin.js';
|
||||||
runWithErrorHandling
|
export { handleRequest } from './request.js';
|
||||||
} from './controller.js';
|
|
||||||
export {
|
|
||||||
default as vitePluginAstroServer
|
|
||||||
} from './plugin.js';
|
|
||||||
export {
|
|
||||||
handleRequest
|
|
||||||
} from './request.js';
|
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
|
|
||||||
import type * as vite from 'vite';
|
import type * as vite from 'vite';
|
||||||
import type { AstroSettings, ManifestData } from '../@types/astro';
|
import type { AstroSettings, ManifestData } from '../@types/astro';
|
||||||
|
|
||||||
|
import type fs from 'fs';
|
||||||
import { LogOptions } from '../core/logger/core.js';
|
import { LogOptions } from '../core/logger/core.js';
|
||||||
|
import { createViteLoader } from '../core/module-loader/index.js';
|
||||||
import { createDevelopmentEnvironment } from '../core/render/dev/index.js';
|
import { createDevelopmentEnvironment } from '../core/render/dev/index.js';
|
||||||
import { createRouteManifest } from '../core/routing/index.js';
|
import { createRouteManifest } from '../core/routing/index.js';
|
||||||
import { createViteLoader } from '../core/module-loader/index.js';
|
|
||||||
import { baseMiddleware } from './base.js';
|
import { baseMiddleware } from './base.js';
|
||||||
import { handleRequest } from './request.js';
|
|
||||||
import { createController } from './controller.js';
|
import { createController } from './controller.js';
|
||||||
import type fs from 'fs';
|
import { handleRequest } from './request.js';
|
||||||
|
|
||||||
export interface AstroPluginOptions {
|
export interface AstroPluginOptions {
|
||||||
settings: AstroSettings;
|
settings: AstroSettings;
|
||||||
|
@ -17,7 +16,11 @@ export interface AstroPluginOptions {
|
||||||
fs: typeof fs;
|
fs: typeof fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function createVitePluginAstroServer({ settings, logging, fs: fsMod }: AstroPluginOptions): vite.Plugin {
|
export default function createVitePluginAstroServer({
|
||||||
|
settings,
|
||||||
|
logging,
|
||||||
|
fs: fsMod,
|
||||||
|
}: AstroPluginOptions): vite.Plugin {
|
||||||
return {
|
return {
|
||||||
name: 'astro:server',
|
name: 'astro:server',
|
||||||
configureServer(viteServer) {
|
configureServer(viteServer) {
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import type http from 'http';
|
import type http from 'http';
|
||||||
import type { ManifestData, RouteData } from '../@types/astro';
|
import type { ManifestData } from '../@types/astro';
|
||||||
import type { DevServerController } from './controller';
|
|
||||||
import type { DevelopmentEnvironment } from '../core/render/dev/index';
|
import type { DevelopmentEnvironment } from '../core/render/dev/index';
|
||||||
|
import type { DevServerController } from './controller';
|
||||||
|
|
||||||
import { collectErrorMetadata } from '../core/errors/dev/index.js';
|
import { collectErrorMetadata } from '../core/errors/dev/index.js';
|
||||||
|
import { createSafeError } from '../core/errors/index.js';
|
||||||
import { error } from '../core/logger/core.js';
|
import { error } from '../core/logger/core.js';
|
||||||
import * as msg from '../core/messages.js';
|
import * as msg from '../core/messages.js';
|
||||||
import { handleRoute, matchRoute } from './route.js';
|
|
||||||
import { handle500Response } from './response.js';
|
|
||||||
import { runWithErrorHandling } from './controller.js';
|
import { runWithErrorHandling } from './controller.js';
|
||||||
import { createSafeError } from '../core/errors/index.js';
|
import { handle500Response } from './response.js';
|
||||||
|
import { handleRoute, matchRoute } from './route.js';
|
||||||
|
|
||||||
/** The main logic to route dev server requests to pages in Astro. */
|
/** The main logic to route dev server requests to pages in Astro. */
|
||||||
export async function handleRequest(
|
export async function handleRequest(
|
||||||
|
@ -60,7 +60,7 @@ export async function handleRequest(
|
||||||
pathname,
|
pathname,
|
||||||
async run() {
|
async run() {
|
||||||
const matchedRoute = await matchRoute(pathname, env, manifest);
|
const matchedRoute = await matchRoute(pathname, env, manifest);
|
||||||
|
|
||||||
return await handleRoute(matchedRoute, url, pathname, body, origin, env, manifest, req, res);
|
return await handleRoute(matchedRoute, url, pathname, body, origin, env, manifest, req, res);
|
||||||
},
|
},
|
||||||
onError(_err) {
|
onError(_err) {
|
||||||
|
@ -73,6 +73,6 @@ export async function handleRequest(
|
||||||
handle500Response(moduleLoader, res, errorWithMetadata);
|
handle500Response(moduleLoader, res, errorWithMetadata);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
import type http from 'http';
|
import type http from 'http';
|
||||||
import type { ModuleLoader } from '../core/module-loader/index';
|
|
||||||
import type { ErrorWithMetadata } from '../core/errors/index.js';
|
import type { ErrorWithMetadata } from '../core/errors/index.js';
|
||||||
|
import type { ModuleLoader } from '../core/module-loader/index';
|
||||||
|
|
||||||
import { Readable } from 'stream';
|
import { Readable } from 'stream';
|
||||||
import { getSetCookiesFromResponse } from '../core/cookies/index.js';
|
import { getSetCookiesFromResponse } from '../core/cookies/index.js';
|
||||||
import { getViteErrorPayload } from '../core/errors/dev/index.js';
|
import { getViteErrorPayload } from '../core/errors/dev/index.js';
|
||||||
import notFoundTemplate from '../template/4xx.js';
|
import notFoundTemplate from '../template/4xx.js';
|
||||||
|
|
||||||
|
|
||||||
export async function handle404Response(
|
export async function handle404Response(
|
||||||
origin: string,
|
origin: string,
|
||||||
req: http.IncomingMessage,
|
req: http.IncomingMessage,
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import type http from 'http';
|
import type http from 'http';
|
||||||
import mime from 'mime';
|
import mime from 'mime';
|
||||||
import type { AstroConfig, AstroSettings, ManifestData } from '../@types/astro';
|
import type { AstroSettings, ManifestData } from '../@types/astro';
|
||||||
import { DevelopmentEnvironment, SSROptions } from '../core/render/dev/index';
|
import { DevelopmentEnvironment, SSROptions } from '../core/render/dev/index';
|
||||||
|
|
||||||
import { attachToResponse } from '../core/cookies/index.js';
|
import { attachToResponse } from '../core/cookies/index.js';
|
||||||
import { call as callEndpoint } from '../core/endpoint/dev/index.js';
|
import { call as callEndpoint } from '../core/endpoint/dev/index.js';
|
||||||
|
import { throwIfRedirectNotAllowed } from '../core/endpoint/index.js';
|
||||||
import { warn } from '../core/logger/core.js';
|
import { warn } from '../core/logger/core.js';
|
||||||
import { appendForwardSlash } from '../core/path.js';
|
import { appendForwardSlash } from '../core/path.js';
|
||||||
import { preload, renderPage } from '../core/render/dev/index.js';
|
import { preload, renderPage } from '../core/render/dev/index.js';
|
||||||
|
@ -13,8 +14,7 @@ import { createRequest } from '../core/request.js';
|
||||||
import { matchAllRoutes } from '../core/routing/index.js';
|
import { matchAllRoutes } from '../core/routing/index.js';
|
||||||
import { resolvePages } from '../core/util.js';
|
import { resolvePages } from '../core/util.js';
|
||||||
import { log404 } from './common.js';
|
import { log404 } from './common.js';
|
||||||
import { handle404Response, writeWebResponse, writeSSRResult } from './response.js';
|
import { handle404Response, writeSSRResult, writeWebResponse } from './response.js';
|
||||||
import { throwIfRedirectNotAllowed } from '../core/endpoint/index.js';
|
|
||||||
|
|
||||||
type AsyncReturnType<T extends (...args: any) => Promise<any>> = T extends (
|
type AsyncReturnType<T extends (...args: any) => Promise<any>> = T extends (
|
||||||
...args: any
|
...args: any
|
||||||
|
@ -29,7 +29,11 @@ function getCustom404Route({ config }: AstroSettings, manifest: ManifestData) {
|
||||||
return manifest.routes.find((r) => r.component.match(pattern));
|
return manifest.routes.find((r) => r.component.match(pattern));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function matchRoute(pathname: string, env: DevelopmentEnvironment, manifest: ManifestData) {
|
export async function matchRoute(
|
||||||
|
pathname: string,
|
||||||
|
env: DevelopmentEnvironment,
|
||||||
|
manifest: ManifestData
|
||||||
|
) {
|
||||||
const { logging, settings, routeCache } = env;
|
const { logging, settings, routeCache } = env;
|
||||||
const matches = matchAllRoutes(pathname, manifest);
|
const matches = matchAllRoutes(pathname, manifest);
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ export interface ServerState {
|
||||||
export function createServerState(): ServerState {
|
export function createServerState(): ServerState {
|
||||||
return {
|
return {
|
||||||
routes: new Map(),
|
routes: new Map(),
|
||||||
state: 'fresh'
|
state: 'fresh',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,14 +23,14 @@ export function hasAnyFailureState(serverState: ServerState) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setRouteError(serverState: ServerState, pathname: string, error: Error) {
|
export function setRouteError(serverState: ServerState, pathname: string, error: Error) {
|
||||||
if(serverState.routes.has(pathname)) {
|
if (serverState.routes.has(pathname)) {
|
||||||
const routeState = serverState.routes.get(pathname)!;
|
const routeState = serverState.routes.get(pathname)!;
|
||||||
routeState.state = 'error';
|
routeState.state = 'error';
|
||||||
routeState.error = error;
|
routeState.error = error;
|
||||||
} else {
|
} else {
|
||||||
const routeState: RouteState = {
|
const routeState: RouteState = {
|
||||||
state: 'error',
|
state: 'error',
|
||||||
error: error
|
error: error,
|
||||||
};
|
};
|
||||||
serverState.routes.set(pathname, routeState);
|
serverState.routes.set(pathname, routeState);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ export function setServerError(serverState: ServerState, error: Error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function clearRouteError(serverState: ServerState, pathname: string) {
|
export function clearRouteError(serverState: ServerState, pathname: string) {
|
||||||
if(serverState.routes.has(pathname)) {
|
if (serverState.routes.has(pathname)) {
|
||||||
serverState.routes.delete(pathname);
|
serverState.routes.delete(pathname);
|
||||||
}
|
}
|
||||||
serverState.state = 'fresh';
|
serverState.state = 'fresh';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import type * as vite from 'vite';
|
|
||||||
import nodeFs from 'fs';
|
import nodeFs from 'fs';
|
||||||
|
import type * as vite from 'vite';
|
||||||
|
|
||||||
type NodeFileSystemModule = typeof nodeFs;
|
type NodeFileSystemModule = typeof nodeFs;
|
||||||
|
|
||||||
|
@ -9,30 +9,29 @@ export interface LoadFallbackPluginParams {
|
||||||
|
|
||||||
export default function loadFallbackPlugin({ fs }: LoadFallbackPluginParams): vite.Plugin | false {
|
export default function loadFallbackPlugin({ fs }: LoadFallbackPluginParams): vite.Plugin | false {
|
||||||
// Only add this plugin if a custom fs implementation is provided.
|
// Only add this plugin if a custom fs implementation is provided.
|
||||||
if(!fs || fs === nodeFs) {
|
if (!fs || fs === nodeFs) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: 'astro:load-fallback',
|
name: 'astro:load-fallback',
|
||||||
enforce: 'post',
|
enforce: 'post',
|
||||||
async load(id) {
|
async load(id) {
|
||||||
try {
|
try {
|
||||||
// await is necessary for the catch
|
// await is necessary for the catch
|
||||||
return await fs.promises.readFile(cleanUrl(id), 'utf-8')
|
return await fs.promises.readFile(cleanUrl(id), 'utf-8');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
try {
|
try {
|
||||||
return await fs.promises.readFile(id, 'utf-8');
|
return await fs.promises.readFile(id, 'utf-8');
|
||||||
} catch(e2) {
|
} catch (e2) {
|
||||||
// Let fall through to the next
|
// Let fall through to the next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const queryRE = /\?.*$/s;
|
const queryRE = /\?.*$/s;
|
||||||
const hashRE = /#.*$/s;
|
const hashRE = /#.*$/s;
|
||||||
|
|
||||||
const cleanUrl = (url: string): string =>
|
const cleanUrl = (url: string): string => url.replace(hashRE, '').replace(queryRE, '');
|
||||||
url.replace(hashRE, '').replace(queryRE, '');
|
|
||||||
|
|
|
@ -25,8 +25,8 @@ function removeTrailingSeparator(str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSeparator(str, i) {
|
function isSeparator(str, i) {
|
||||||
let char = str[i];
|
let char = str[i];
|
||||||
return i > 0 && (char === '/' || (isWin && char === '\\'));
|
return i > 0 && (char === '/' || (isWin && char === '\\'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -37,34 +37,34 @@ function isSeparator(str, i) {
|
||||||
* Released under the MIT License.
|
* Released under the MIT License.
|
||||||
*/
|
*/
|
||||||
function normalizePath(str, stripTrailing) {
|
function normalizePath(str, stripTrailing) {
|
||||||
if (typeof str !== 'string') {
|
if (typeof str !== 'string') {
|
||||||
throw new TypeError('expected a string');
|
throw new TypeError('expected a string');
|
||||||
}
|
}
|
||||||
str = str.replace(/[\\\/]+/g, '/');
|
str = str.replace(/[\\\/]+/g, '/');
|
||||||
if (stripTrailing !== false) {
|
if (stripTrailing !== false) {
|
||||||
str = removeTrailingSeparator(str);
|
str = removeTrailingSeparator(str);
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* unixify <https://github.com/jonschlinkert/unixify>
|
* unixify <https://github.com/jonschlinkert/unixify>
|
||||||
*
|
*
|
||||||
* Inlined from:
|
* Inlined from:
|
||||||
* Copyright (c) 2014, 2017, Jon Schlinkert.
|
* Copyright (c) 2014, 2017, Jon Schlinkert.
|
||||||
* Released under the MIT License.
|
* Released under the MIT License.
|
||||||
*/
|
*/
|
||||||
export function unixify(filepath, stripTrailing = true) {
|
export function unixify(filepath, stripTrailing = true) {
|
||||||
if(isWin) {
|
if (isWin) {
|
||||||
filepath = normalizePath(filepath, stripTrailing);
|
filepath = normalizePath(filepath, stripTrailing);
|
||||||
return filepath.replace(/^([a-zA-Z]+:|\.\/)/, '');
|
return filepath.replace(/^([a-zA-Z]+:|\.\/)/, '');
|
||||||
}
|
}
|
||||||
return filepath;
|
return filepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Corrects a windows path to unix format (including \\?\c:...)
|
* Corrects a windows path to unix format (including \\?\c:...)
|
||||||
*/
|
*/
|
||||||
export function correctPath(filepath) {
|
export function correctPath(filepath) {
|
||||||
return unixify(filepath.replace(/^\\\\\?\\.:\\/,'\\'));
|
return unixify(filepath.replace(/^\\\\\?\\.:\\/, '\\'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,9 @@ const root = new URL('../../fixtures/alias/', import.meta.url);
|
||||||
|
|
||||||
describe('dev container', () => {
|
describe('dev container', () => {
|
||||||
it('can render requests', async () => {
|
it('can render requests', async () => {
|
||||||
|
const fs = createFs(
|
||||||
const fs = createFs({
|
{
|
||||||
'/src/pages/index.astro': `
|
'/src/pages/index.astro': `
|
||||||
---
|
---
|
||||||
const name = 'Testing';
|
const name = 'Testing';
|
||||||
---
|
---
|
||||||
|
@ -20,13 +20,15 @@ describe('dev container', () => {
|
||||||
<h1>{name}</h1>
|
<h1>{name}</h1>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`
|
`,
|
||||||
}, root);
|
},
|
||||||
|
root
|
||||||
|
);
|
||||||
|
|
||||||
await runInContainer({ fs, root }, async container => {
|
await runInContainer({ fs, root }, async (container) => {
|
||||||
const { req, res, text } = createRequestAndResponse({
|
const { req, res, text } = createRequestAndResponse({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/'
|
url: '/',
|
||||||
});
|
});
|
||||||
container.handle(req, res);
|
container.handle(req, res);
|
||||||
const html = await text();
|
const html = await text();
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { unixify } from './correct-path.js';
|
||||||
|
|
||||||
class MyVolume extends Volume {
|
class MyVolume extends Volume {
|
||||||
existsSync(p) {
|
existsSync(p) {
|
||||||
if(p instanceof URL) {
|
if (p instanceof URL) {
|
||||||
p = fileURLToPath(p);
|
p = fileURLToPath(p);
|
||||||
}
|
}
|
||||||
return super.existsSync(p);
|
return super.existsSync(p);
|
||||||
|
@ -15,12 +15,12 @@ class MyVolume extends Volume {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createFs(json, root) {
|
export function createFs(json, root) {
|
||||||
if(typeof root !== 'string') {
|
if (typeof root !== 'string') {
|
||||||
root = unixify(fileURLToPath(root));
|
root = unixify(fileURLToPath(root));
|
||||||
}
|
}
|
||||||
|
|
||||||
const structure = {};
|
const structure = {};
|
||||||
for(const [key, value] of Object.entries(json)) {
|
for (const [key, value] of Object.entries(json)) {
|
||||||
const fullpath = npath.posix.join(root, key);
|
const fullpath = npath.posix.join(root, key);
|
||||||
structure[fullpath] = value;
|
structure[fullpath] = value;
|
||||||
}
|
}
|
||||||
|
@ -61,8 +61,8 @@ export function toPromise(res) {
|
||||||
// node-mocks-http doesn't correctly handle non-Buffer typed arrays,
|
// node-mocks-http doesn't correctly handle non-Buffer typed arrays,
|
||||||
// so override the write method to fix it.
|
// so override the write method to fix it.
|
||||||
const write = res.write;
|
const write = res.write;
|
||||||
res.write = function(data, encoding) {
|
res.write = function (data, encoding) {
|
||||||
if(ArrayBuffer.isView(data) && !Buffer.isBuffer(data)) {
|
if (ArrayBuffer.isView(data) && !Buffer.isBuffer(data)) {
|
||||||
data = Buffer.from(data);
|
data = Buffer.from(data);
|
||||||
}
|
}
|
||||||
return write.call(this, data, encoding);
|
return write.call(this, data, encoding);
|
||||||
|
@ -77,7 +77,7 @@ export function toPromise(res) {
|
||||||
export function buffersToString(buffers) {
|
export function buffersToString(buffers) {
|
||||||
let decoder = new TextDecoder();
|
let decoder = new TextDecoder();
|
||||||
let str = '';
|
let str = '';
|
||||||
for(const buffer of buffers) {
|
for (const buffer of buffers) {
|
||||||
str += decoder.decode(buffer);
|
str += decoder.decode(buffer);
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import { createLoader } from '../../../dist/core/module-loader/index.js';
|
import { createLoader } from '../../../dist/core/module-loader/index.js';
|
||||||
import { createController, runWithErrorHandling } from '../../../dist/vite-plugin-astro-server/index.js';
|
import {
|
||||||
|
createController,
|
||||||
|
runWithErrorHandling,
|
||||||
|
} from '../../../dist/vite-plugin-astro-server/index.js';
|
||||||
|
|
||||||
describe('vite-plugin-astro-server', () => {
|
describe('vite-plugin-astro-server', () => {
|
||||||
describe('controller', () => {
|
describe('controller', () => {
|
||||||
|
@ -15,7 +18,7 @@ describe('vite-plugin-astro-server', () => {
|
||||||
},
|
},
|
||||||
onError(err) {
|
onError(err) {
|
||||||
error = err;
|
error = err;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
expect(error).to.not.be.an('undefined');
|
expect(error).to.not.be.an('undefined');
|
||||||
expect(error).to.be.an.instanceOf(Error);
|
expect(error).to.be.an.instanceOf(Error);
|
||||||
|
@ -29,7 +32,7 @@ describe('vite-plugin-astro-server', () => {
|
||||||
run() {
|
run() {
|
||||||
throw new Error('oh no');
|
throw new Error('oh no');
|
||||||
},
|
},
|
||||||
onError(){}
|
onError() {},
|
||||||
});
|
});
|
||||||
expect(controller.state.state).to.equal('error');
|
expect(controller.state.state).to.equal('error');
|
||||||
});
|
});
|
||||||
|
@ -40,7 +43,7 @@ describe('vite-plugin-astro-server', () => {
|
||||||
eachModule() {},
|
eachModule() {},
|
||||||
clientReload() {
|
clientReload() {
|
||||||
reloads++;
|
reloads++;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const controller = createController({ loader });
|
const controller = createController({ loader });
|
||||||
loader.events.emit('file-change');
|
loader.events.emit('file-change');
|
||||||
|
@ -51,7 +54,7 @@ describe('vite-plugin-astro-server', () => {
|
||||||
run() {
|
run() {
|
||||||
throw new Error('oh no');
|
throw new Error('oh no');
|
||||||
},
|
},
|
||||||
onError(){}
|
onError() {},
|
||||||
});
|
});
|
||||||
expect(reloads).to.equal(0);
|
expect(reloads).to.equal(0);
|
||||||
loader.events.emit('file-change');
|
loader.events.emit('file-change');
|
||||||
|
@ -64,7 +67,7 @@ describe('vite-plugin-astro-server', () => {
|
||||||
eachModule() {},
|
eachModule() {},
|
||||||
clientReload() {
|
clientReload() {
|
||||||
reloads++;
|
reloads++;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const controller = createController({ loader });
|
const controller = createController({ loader });
|
||||||
loader.events.emit('file-change');
|
loader.events.emit('file-change');
|
||||||
|
@ -75,7 +78,7 @@ describe('vite-plugin-astro-server', () => {
|
||||||
run() {
|
run() {
|
||||||
throw new Error('oh no');
|
throw new Error('oh no');
|
||||||
},
|
},
|
||||||
onError(){}
|
onError() {},
|
||||||
});
|
});
|
||||||
expect(reloads).to.equal(0);
|
expect(reloads).to.equal(0);
|
||||||
loader.events.emit('file-change');
|
loader.events.emit('file-change');
|
||||||
|
@ -87,7 +90,7 @@ describe('vite-plugin-astro-server', () => {
|
||||||
controller,
|
controller,
|
||||||
pathname: '/',
|
pathname: '/',
|
||||||
// No error here
|
// No error here
|
||||||
run() {}
|
run() {},
|
||||||
});
|
});
|
||||||
loader.events.emit('file-change');
|
loader.events.emit('file-change');
|
||||||
expect(reloads).to.equal(2);
|
expect(reloads).to.equal(2);
|
||||||
|
@ -106,7 +109,7 @@ describe('vite-plugin-astro-server', () => {
|
||||||
},
|
},
|
||||||
invalidateModule(mod) {
|
invalidateModule(mod) {
|
||||||
mod.ssrError = null;
|
mod.ssrError = null;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const controller = createController({ loader });
|
const controller = createController({ loader });
|
||||||
|
|
||||||
|
@ -116,9 +119,9 @@ describe('vite-plugin-astro-server', () => {
|
||||||
run() {
|
run() {
|
||||||
throw new Error('oh no');
|
throw new Error('oh no');
|
||||||
},
|
},
|
||||||
onError(){}
|
onError() {},
|
||||||
});
|
});
|
||||||
|
|
||||||
loader.events.emit('file-change');
|
loader.events.emit('file-change');
|
||||||
|
|
||||||
expect(mods).to.deep.equal([
|
expect(mods).to.deep.equal([
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { createRequestAndResponse, createFs, createAstroModule } from '../test-u
|
||||||
async function createDevEnvironment(overrides = {}) {
|
async function createDevEnvironment(overrides = {}) {
|
||||||
const env = createBasicEnvironment({
|
const env = createBasicEnvironment({
|
||||||
logging,
|
logging,
|
||||||
renderers: []
|
renderers: [],
|
||||||
});
|
});
|
||||||
env.settings = await createDefaultDevSettings({}, '/');
|
env.settings = await createDefaultDevSettings({}, '/');
|
||||||
env.settings.renderers = [];
|
env.settings.renderers = [];
|
||||||
|
@ -31,31 +31,31 @@ describe('vite-plugin-astro-server', () => {
|
||||||
return render`<div id="test">testing</div>`;
|
return render`<div id="test">testing</div>`;
|
||||||
});
|
});
|
||||||
return createAstroModule(Page);
|
return createAstroModule(Page);
|
||||||
}
|
},
|
||||||
})
|
}),
|
||||||
});
|
});
|
||||||
const controller = createController({ loader: env.loader });
|
const controller = createController({ loader: env.loader });
|
||||||
const { req, res, text } = createRequestAndResponse();
|
const { req, res, text } = createRequestAndResponse();
|
||||||
const fs = createFs({
|
const fs = createFs(
|
||||||
// Note that the content doesn't matter here because we are using a custom loader.
|
{
|
||||||
'/src/pages/index.astro': ''
|
// Note that the content doesn't matter here because we are using a custom loader.
|
||||||
}, '/');
|
'/src/pages/index.astro': '',
|
||||||
const manifest = createRouteManifest({
|
},
|
||||||
fsMod: fs,
|
'/'
|
||||||
settings: env.settings
|
);
|
||||||
}, logging);
|
const manifest = createRouteManifest(
|
||||||
|
{
|
||||||
|
fsMod: fs,
|
||||||
|
settings: env.settings,
|
||||||
|
},
|
||||||
|
logging
|
||||||
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await handleRequest(
|
await handleRequest(env, manifest, controller, req, res);
|
||||||
env,
|
|
||||||
manifest,
|
|
||||||
controller,
|
|
||||||
req,
|
|
||||||
res
|
|
||||||
);
|
|
||||||
const html = await text();
|
const html = await text();
|
||||||
expect(html).to.include('<div id="test">');
|
expect(html).to.include('<div id="test">');
|
||||||
} catch(err) {
|
} catch (err) {
|
||||||
expect(err).to.be.undefined();
|
expect(err).to.be.undefined();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue