Socket
Socket
Sign inDemoInstall

@gracile/engine

Package Overview
Dependencies
Maintainers
0
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@gracile/engine - npm Package Compare versions

Comparing version 0.7.0-next.0 to 0.7.0-next.1

dist/dev/vite-logger.d.ts

7

dist/build/static.js
import { Buffer } from 'node:buffer';
import path, { join } from 'node:path';
import { logger } from '@gracile/internal-utils/logger';
import { getLogger } from '@gracile/internal-utils/logger/helpers';
import c from 'picocolors';

@@ -21,2 +21,3 @@ import { renderRouteTemplate } from '../render/route-template.js';

export async function renderRoutes({ routes, vite, serverMode, root = process.cwd(), gracileConfig, }) {
const logger = getLogger();
logger.info(c.green('Rendering routes…'), { timestamp: true });

@@ -87,2 +88,4 @@ // MARK: Collect

name = '404.html';
if (name === '500/index.html')
name = '500.html';
const url = new URL(pathnameWithParams, 'http://gracile-static');

@@ -108,2 +111,4 @@ // MARK: Render

const existing = renderedRoutes.find((rendered) => rendered?.name === name);
// NOTE: IIRC, this happens when two or more routes has the
// same priority, that will output the same static path.
if (existing)

@@ -110,0 +115,0 @@ throw new Error(`${c.red(`"${existing.name}" page was defined twice!`)}\n`);

39

dist/dev/dev.js

@@ -1,24 +0,31 @@

import { logger } from '@gracile/internal-utils/logger';
import { getLogger } from '@gracile/internal-utils/logger/helpers';
import c from 'picocolors';
import {} from 'vite';
import { collectRoutes } from '../routes/collect.js';
import { collectRoutes, WATCHED_FILES_REGEX } from '../routes/collect.js';
import { createGracileHandler, } from '../server/request.js';
import { generateRoutesTypings } from './route-typings.js';
export async function createDevHandler({ routes, vite, gracileConfig, }) {
const logger = getLogger();
const root = vite.config.root;
logger.info(c.dim('\nCreating handler…'), { timestamp: true });
await collectRoutes(routes, root, gracileConfig.routes?.exclude);
if (gracileConfig.experimental?.generateRoutesTypings)
generateRoutesTypings(root, routes).catch((error) => logger.error(String(error)));
logger.info('');
logger.info(c.dim('Creating the request handler…'), { timestamp: true });
const collect = async () => {
await collectRoutes(routes, root, gracileConfig.routes?.exclude);
if (gracileConfig.experimental?.generateRoutesTypings)
await generateRoutesTypings(root, routes).catch((error) => logger.error(String(error)));
};
await collect();
let wait;
vite.watcher.on('all', (event, file) => {
// console.log({ event });
if (file.match(/\/src\/routes\/(.*)\.(ts|js|css|scss|sass|less|styl|stylus)$/) &&
['add', 'unlink'].includes(event))
collectRoutes(routes, root, gracileConfig.routes?.exclude)
.then(() => {
vite.hot.send('vite:invalidate');
if (gracileConfig.experimental?.generateRoutesTypings)
generateRoutesTypings(root, routes).catch((error) => logger.error(String(error)));
})
.catch((e) => logger.error(String(e)));
if (file.match(WATCHED_FILES_REGEX) &&
['add', 'unlink'].includes(event)
//
) {
clearTimeout(wait);
wait = setTimeout(() => {
collect()
.then(() => vite.hot.send('vite:invalidate'))
.catch((error) => logger.error(String(error)));
}, 100);
}
});

@@ -25,0 +32,0 @@ //

import { join } from 'node:path';
import { logger } from '@gracile/internal-utils/logger';
import { createLogger } from '@gracile/internal-utils/logger/helpers';
import { getVersion } from '@gracile/internal-utils/version';
import { betterErrors } from '@gracile-labs/better-errors/plugin';
import { rename, rm } from 'fs/promises';

@@ -34,2 +36,3 @@ import c from 'picocolors';

export const gracile = (config) => {
const logger = createLogger();
const outputMode = config?.output || 'static';

@@ -53,2 +56,5 @@ const clientAssets = {};

return [
betterErrors({
overlayImportPath: '@gracile/gracile/_internals/vite-custom-overlay',
}),
// {

@@ -79,10 +85,15 @@ // name: 'gracile-routes-codegen',

// },
virtualRoutesForClient,
{
name: 'vite-plugin-gracile-serve-middleware',
apply: 'serve',
config() {
config(_, env) {
if (env.isPreview)
return null;
return {
// NOTE: Supresses message: `Could not auto-determine entry point from rollupOptions or html files…`
// FIXME: It's not working when reloading the Vite config.
// Is user config, putting `optimizeDeps: { include: [] }` solve this.
optimizeDeps: { include: [] },
// NOTE: Useful? It breaks preview (expected)
appType: 'custom',
// resolve: {

@@ -108,3 +119,3 @@ // conditions: ['development'],

// };
const version = process.env['__GRACILE_VERSION__'];
const version = getVersion();
logger.info(`${c.cyan(c.italic(c.underline('🧚 Gracile')))}` +

@@ -118,6 +129,19 @@ ` ${c.dim(`~`)} ${c.green(`v${version ?? 'X'}`)}`);

});
logger.info(c.dim('Vite development server is starting…'), {
timestamp: true,
});
server.watcher.on('ready', () => {
setTimeout(() => {
logger.info('');
logger.info(c.green('Watching for file changes…'), {
timestamp: true,
});
logger.info('');
}, 100);
// s
});
return () => {
server.middlewares.use((req, res, next) => {
const locals = config?.dev?.locals?.({ nodeRequest: req });
Promise.resolve(nodeAdapter(handler)(req, res, locals)).catch((error) => next(error));
Promise.resolve(nodeAdapter(handler, { logger })(req, res, locals)).catch((error) => next(error));
});

@@ -127,2 +151,3 @@ };

},
virtualRoutesForClient,
{

@@ -233,3 +258,6 @@ name: 'vite-plugin-gracile-build',

import { createGracileHandler } from '@gracile/gracile/_internals/server-runtime';
import { createLogger } from '@gracile/gracile/_internals/logger';
createLogger();
export const handler = createGracileHandler({

@@ -236,0 +264,0 @@ root: process.cwd(),

import { Readable } from 'node:stream';
import * as assert from '@gracile/internal-utils/assertions';
import { html } from '@gracile/internal-utils/dummy-literals';
import { render as renderLitSsr } from '@lit-labs/ssr';
import { collectResult } from '@lit-labs/ssr/lib/render-result.js';
import { isLitServerTemplate, isLitTemplate } from '../assertions.js';
import { GracileError, GracileErrorData, TemplateError, } from '../errors/errors.js';
import { PAGE_ASSETS_MARKER, SSR_OUTLET_MARKER } from './markers.js';

@@ -19,2 +20,5 @@ async function* concatStreams(...readables) {

export async function renderRouteTemplate({ url, vite, mode, routeInfos, routeAssets, serverMode, docOnly, }) {
const location = {
file: routeInfos.foundRoute.filePath,
};
if (!routeInfos.routeModule.document && !routeInfos.routeModule.template)

@@ -31,4 +35,8 @@ return { output: null, document: null };

const fragmentOutput = await Promise.resolve(routeInfos.routeModule.template?.(context));
if (isLitTemplate(fragmentOutput) === false)
throw Error(`Wrong template result for fragment template ${routeInfos.foundRoute.filePath}.`);
if (assert.isLitTemplate(fragmentOutput) === false)
throw new GracileError({
...GracileErrorData.InvalidRouteDocument,
message: GracileErrorData.InvalidRouteDocument.message(location.file),
// location,
});
const fragmentRender = renderLitSsr(fragmentOutput);

@@ -41,7 +49,26 @@ const output = Readable.from(fragmentRender);

typeof routeInfos.routeModule.document !== 'function')
throw new TypeError(`Route document must be a function ${routeInfos.foundRoute.filePath}.`);
throw new GracileError({
...GracileErrorData.InvalidRouteDocument,
message: GracileErrorData.InvalidRouteDocument.message(location.file),
location,
});
const baseDocTemplateResult = await Promise.resolve(routeInfos.routeModule.document?.(context));
if (isLitServerTemplate(baseDocTemplateResult) === false)
throw new TypeError(`Incorrect document template result for ${routeInfos.foundRoute.filePath}.`);
const baseDocRendered = await collectResult(renderLitSsr(baseDocTemplateResult));
if (assert.isLitServerTemplate(baseDocTemplateResult) === false)
throw new GracileError({
...GracileErrorData.InvalidRouteDocumentResult,
message: GracileErrorData.InvalidRouteDocumentResult.message(location.file),
location,
});
let baseDocRendered;
// console.log({ ddd: baseDocTemplateResult });
try {
baseDocRendered = await collectResult(renderLitSsr(baseDocTemplateResult));
}
catch (e) {
throw new TemplateError({
...GracileErrorData.CouldNotRenderRouteDocument,
message: GracileErrorData.CouldNotRenderRouteDocument.message(location.file),
location,
}, { cause: String(e) });
}
// MARK: Sibling assets

@@ -68,3 +95,4 @@ let baseDocRenderedWithAssets = baseDocRendered;

}
throw new Error('Unknown asset.');
// NOTE: Never called (filtered upstream in `collectRoutes`)
return null;
})

@@ -135,3 +163,3 @@ .join('\n')}` +

// }
if (isLitTemplate(routeOutput) === false)
if (assert.isLitTemplate(routeOutput) === false)
throw Error(`Wrong template result for page template ${routeInfos.foundRoute.filePath}.`);

@@ -138,0 +166,0 @@ const renderStream = Readable.from(renderLitSsr(routeOutput));

import type * as R from './route.js';
export declare function collectRoutes(routes: R.RoutesManifest, root: string, excludePatterns?: string[]): Promise<R.RoutesManifest>;
export declare const WATCHED_FILES_REGEX: RegExp;
export declare function collectRoutes(routes: R.RoutesManifest, root: string, excludePatterns?: string[]): Promise<void>;
//# sourceMappingURL=collect.d.ts.map
import { join } from 'node:path';
import { logger } from '@gracile/internal-utils/logger';
import { getLogger } from '@gracile/internal-utils/logger/helpers';
import * as paths from '@gracile/internal-utils/paths';

@@ -8,11 +8,12 @@ import { fdir as Fdir } from 'fdir';

import { createFilter } from 'vite';
// import type { ViteDevServer } from 'vite';
import { emptyRoutes } from '../logging/messages.js';
import { prepareSortableRoutes, routeComparator } from './comparator.js';
import { REGEXES } from './load-module.js';
const logger = getLogger();
function extractRoutePatterns(routeFilePath) {
const routePathname = routeFilePath.replace(/\.[j|t]s$/, '');
let pathParts = routePathname.split(process.platform === 'win32' ? '\\' : '/');
let pathParts = routePathname.split(paths.isWindows() ? paths.WINDOWS_PATH_SEPARATOR : '/');
const last = pathParts.at(-1);
if (typeof last === 'undefined')
throw new TypeError('Cannot parse file path.');
if (last === undefined)
throw new ReferenceError('Cannot parse file path.');
if (

@@ -26,5 +27,2 @@ // NOTE: /foo/(foo) => /foo

pathParts = [];
// NOTE: Disabled for now, but might be useful later
// if (pathParts.length === 1 && pathParts.at(0) === '404')
// pathParts = ['__404'];
let hasParams = false;

@@ -53,2 +51,3 @@ const pathRelNorm = pathParts.map((pathEntry) => {

}
export const WATCHED_FILES_REGEX = /\/src\/routes\/(.*)\.(ts|js|css|scss|sass|less|styl|stylus)$/;
// const routes: R.RoutesManifest = new Map<string, R.Route>();

@@ -75,2 +74,8 @@ export async function collectRoutes(routes, root /* vite: ViteDevServer */, excludePatterns = []) {

const serverEntrypoints = allFilesInRoutes.filter((f) => serverEntrypointsFilter(f));
if (serverEntrypoints.length === 0) {
logger.warnOnce(emptyRoutes(), {
timestamp: true,
});
return;
}
// MARK: Routes priority order

@@ -124,3 +129,2 @@ // TODO: `prepareSortableRoutes` and `routeComparator` in same function `sortRoutes`

});
return routes;
}

@@ -1,2 +0,2 @@

import type { ViteDevServer } from 'vite';
import { type ViteDevServer } from 'vite';
import * as R from './route.js';

@@ -3,0 +3,0 @@ export declare const REGEXES: {

@@ -0,1 +1,7 @@

import { collectErrorMetadata } from '@gracile-labs/better-errors/dev/utils';
import { enhanceViteSSRError } from '@gracile-labs/better-errors/dev/vite';
import { join } from 'path';
import { pathToFileURL } from 'url';
import {} from 'vite';
import { GracileError, GracileErrorData } from '../errors/errors.js';
import * as R from './route.js';

@@ -12,7 +18,28 @@ // const ROUTE_SPREAD = /^\.{3}.+$/;

};
const incorrectRouteModuleError = (p) => new GracileError({
...GracileErrorData.InvalidRouteExport,
message: GracileErrorData.InvalidRouteExport.message(p),
});
export async function loadForeignRouteObject({ vite, route, routeImports, }) {
// NOTE: Check and assert unknown userland module to correct RouteModule instance (in the engine's realm)
let unknownRouteModule = null;
if (vite)
unknownRouteModule = await vite.ssrLoadModule(route.filePath);
if (vite) {
try {
unknownRouteModule = await vite.ssrLoadModule(route.filePath /* + 's' */, {});
}
catch (e) {
const err = e;
const filePath = pathToFileURL(join(vite.config.root, route.filePath));
const rootFolder = pathToFileURL(vite.config.root);
// NOTE: Maybe it's not required here? But just upstream (safeError…)
const enhance = enhanceViteSSRError({
error: err,
filePath,
// @ts-expect-error Typings mismatches
vite,
});
const errorWithMetadata = collectErrorMetadata(enhance, rootFolder);
throw errorWithMetadata;
}
}
else if (routeImports) {

@@ -26,9 +53,8 @@ const ri = routeImports.get(route.pattern.pathname);

const routeModuleFactory = unknownRouteModule['default'];
const errorBase = `Incorrect route module ${route.filePath}!`;
if (typeof routeModuleFactory !== 'function')
throw new TypeError(`${errorBase} Not a function.`);
throw incorrectRouteModuleError(route.filePath);
const routeModule = routeModuleFactory(R.RouteModule);
if (routeModule instanceof R.RouteModule === false)
throw new TypeError(`${errorBase} Not a RouteModule.`);
throw incorrectRouteModuleError(route.filePath);
return routeModule;
}

@@ -16,4 +16,4 @@ import type { ViteDevServer } from 'vite';

routeImports?: R.RoutesImports | undefined;
}): Promise<RouteInfos>;
}): Promise<RouteInfos | null>;
export {};
//# sourceMappingURL=match.d.ts.map

@@ -18,3 +18,3 @@ import { loadForeignRouteObject } from './load-module.js';

if (!match || !foundRoute)
throw new Error(`No route matching for ${url}`, { cause: 404 });
return null;
const params = Object.freeze({ ...match.pathname.groups });

@@ -42,8 +42,17 @@ return { match, foundRoute, params, pathname };

if (hasCorrectParams === false)
throw new Error(`Incorrect route parameters for \`${options.pathname}\`.\n` +
`Check \`staticPaths\` for \`${options.foundRoute.filePath}\`.`);
// throw new Error(
// `Incorrect route parameters for \`${options.pathname}\`.\n` +
// `Check \`staticPaths\` for \`${options.foundRoute.filePath}\`.`,
// );
return null;
return { staticPaths, props };
}
export async function getRoute(options) {
const { foundRoute, pathname, params } = matchRouteFromUrl(options.url, options.routes);
// throw new GracileError(new Error(`No route matching for ${url}`), {
// cause: 404,
// });
const matchedRoute = matchRouteFromUrl(options.url, options.routes);
if (!matchedRoute)
return matchedRoute;
const { foundRoute, pathname, params } = matchedRoute;
// TODO: Simplify all the routes things

@@ -55,8 +64,13 @@ const routeModule = await loadForeignRouteObject({

});
const staticPaths = await extractStaticPaths({
routeModule,
foundRoute,
pathname,
params,
});
let staticPaths = null;
if (routeModule.staticPaths) {
staticPaths = await extractStaticPaths({
routeModule,
foundRoute,
pathname,
params,
});
if (!staticPaths)
return null;
}
return {

@@ -63,0 +77,0 @@ params,

@@ -27,3 +27,3 @@ import type { ServerRenderedTemplate } from '@lit-labs/ssr';

get locals(): {};
get handler(): Handler<object | Response | undefined> | Partial<Record<MethodHtml, Handler<object | Response | undefined>> & Record<MethodNonHtml, Handler<Response>>> | undefined;
get handler(): HandlerGeneric | undefined;
get document(): DocumentTemplate<RouteContextGeneric> | undefined;

@@ -30,0 +30,0 @@ get prerender(): boolean | undefined;

@@ -39,16 +39,18 @@ /* eslint-disable @typescript-eslint/no-explicit-any */

constructor(options) {
if (typeof options.staticPaths === 'function')
this.#staticPaths = options.staticPaths;
if ((typeof options.handler === 'object' ||
typeof options.handler === 'function') &&
options.handler)
this.#handler = options.handler;
// if (typeof options.staticPaths === 'function')
this.#staticPaths = options.staticPaths;
// if (
// (typeof options.handler === 'object' ||
// typeof options.handler === 'function') &&
// options.handler
// )
this.#handler = options.handler;
this.#locals = {};
if (typeof options.template === 'function')
this.#template = options.template;
if (typeof options.document === 'function')
this.#document = options.document;
if (typeof options.prerender === 'boolean')
this.#prerender = options.prerender;
// if (typeof options.template === 'function')
this.#template = options.template;
// if (typeof options.document === 'function')
this.#document = options.document;
// if (typeof options.prerender === 'boolean')
this.#prerender = options.prerender;
}
}

@@ -1,2 +0,2 @@

import type { GracileHandler } from '../request.js';
import type { AdapterOptions, GracileHandler } from '../request.js';
export type { GracileHandler };

@@ -9,4 +9,7 @@ export type GracileHonoHandler = (context: {

}) => Promise<Response>;
export interface HonoAdapterOptions extends AdapterOptions {
}
/**
* @param handler - Takes a pre-built Gracile handler from `./dist/server/entrypoint.js`.
* @param options - If you need more control.
* @example

@@ -29,3 +32,3 @@ * `/src/server.js`

*/
export declare const honoAdapter: (handler: GracileHandler) => GracileHonoHandler;
export declare const honoAdapter: (handler: GracileHandler, options?: HonoAdapterOptions) => GracileHonoHandler;
/**

@@ -32,0 +35,0 @@ *

@@ -1,8 +0,10 @@

// import { logger } from '@gracile/internal-utils/logger';
import { relative } from 'node:path';
import { Readable } from 'node:stream';
import { fileURLToPath } from 'node:url';
import { createLogger } from '@gracile/internal-utils/logger/helpers';
import { GracileError, GracileErrorData } from '../../errors/errors.js';
import { constants } from '../constants.js';
/**
* @param handler - Takes a pre-built Gracile handler from `./dist/server/entrypoint.js`.
* @param options - If you need more control.
* @example

@@ -25,3 +27,4 @@ * `/src/server.js`

*/
export const honoAdapter = (handler) => async (context) => {
export const honoAdapter = (handler, options) => async (context) => {
createLogger(options?.logger);
const result = await handler(context.req.raw, context.var);

@@ -36,3 +39,6 @@ // TODO: Handle stream abortion as gracefully as with Express.

return result.response;
throw new Error('Rendering was impossible in the Hono adapter!');
throw new GracileError({
...GracileErrorData.InvalidResponseInAdapter,
message: GracileErrorData.InvalidResponseInAdapter.message('Hono'),
});
};

@@ -39,0 +45,0 @@ /**

import type { IncomingMessage, ServerResponse } from 'http';
import { type GracileHandler } from '../request.js';
import { type AdapterOptions, type GracileHandler } from '../request.js';
export type { GracileHandler };
export type GracileNodeHandler = (req: IncomingMessage, res: ServerResponse, locals?: unknown) => Promise<ServerResponse<IncomingMessage> | null | void>;
export interface NodeAdapterOptions extends AdapterOptions {
}
/**

@@ -23,3 +25,3 @@ * @param handler - Takes a pre-built Gracile handler from `./dist/server/entrypoint.js`.

*/
export declare function nodeAdapter(handler: GracileHandler): GracileNodeHandler;
export declare function nodeAdapter(handler: GracileHandler, options?: NodeAdapterOptions): GracileNodeHandler;
/**

@@ -26,0 +28,0 @@ * @param root - resolve `dist/client` from this file path.

import { Writable } from 'node:stream';
import { fileURLToPath } from 'node:url';
import { env } from '@gracile/internal-utils/env';
import { logger } from '@gracile/internal-utils/logger';
import { createLogger } from '@gracile/internal-utils/logger/helpers';
import { createServerAdapter } from '@whatwg-node/server';
import { GracileError, GracileErrorData } from '../../errors/errors.js';
import { constants } from '../constants.js';
import { isRedirect } from '../request.js';
import { isRedirect, } from '../request.js';
// NOTE: Find a more canonical way to ponyfill the Node HTTP request to standard Request

@@ -39,7 +40,19 @@ // @ts-expect-error Abusing this feature!

*/
export function nodeAdapter(handler) {
export function nodeAdapter(handler, options) {
return async function nodeHandler(req, res, locals) {
const request = (await Promise.resolve(nodeRequestToStandardRequest.handleNodeRequest(
// HACK: Incorrect typings
req)));
const logger = createLogger(options?.logger);
let webRequest;
try {
webRequest = (await Promise.resolve(nodeRequestToStandardRequest.handleNodeRequest(
// HACK: Exact optional properties
req)));
}
catch (e) {
throw new GracileError({
...GracileErrorData.InvalidRequestInAdapter,
message: GracileErrorData.InvalidRequestInAdapter.message('Node'),
}, {
cause: e,
});
}
const mergedLocals = {

@@ -49,3 +62,3 @@ ...(locals ?? {}),

};
const result = await handler(request, mergedLocals);
const result = await handler(webRequest, mergedLocals);
if (result?.body) {

@@ -75,5 +88,7 @@ standardResponseInitToNodeResponse(result.init, res);

}
return null;
}
return null;
throw new GracileError({
...GracileErrorData.InvalidResponseInAdapter,
message: GracileErrorData.InvalidResponseInAdapter.message('Node'),
});
};

@@ -80,0 +95,0 @@ }

import { Readable } from 'node:stream';
import type { ViteDevServer } from 'vite';
import type { Logger, ViteDevServer } from 'vite';
import type * as R from '../routes/route.js';

@@ -15,2 +15,5 @@ import type { GracileConfig } from '../user-config.js';

};
export interface AdapterOptions {
logger?: Logger;
}
/**

@@ -17,0 +20,0 @@ * The underlying handler interface that you can use to build your own adapter.

import { Readable } from 'node:stream';
import { logger } from '@gracile/internal-utils/logger';
// import { logger } from '@gracile/internal-utils/logger/vite-logger';
import * as assert from '@gracile/internal-utils/assertions';
import { getLogger } from '@gracile/internal-utils/logger/helpers';
import c from 'picocolors';
import * as assert from '../assertions.js';
import { errorPage } from '../errors/templates.js';
import { GracileError } from '../errors/errors.js';
import { builtIn404Page, builtInErrorPage } from '../errors/pages.js';
import { renderRouteTemplate } from '../render/route-template.js';

@@ -19,12 +19,9 @@ import { renderLitTemplate } from '../render/utils.js';

export function createGracileHandler({ vite, routes, routeImports, routeAssets, root, serverMode, gracileConfig, }) {
async function createErrorPage(urlPath, e) {
logger.error(e.message);
let errorPageHtml = await renderLitTemplate(errorPage(e));
const logger = getLogger();
const middleware = async (request, locals) => {
const { url: requestedUrl, method } = request;
let emitViteBetterError = null;
if (vite)
errorPageHtml = await vite.transformIndexHtml(urlPath, errorPageHtml);
return { errorPageHtml, headers: { ...CONTENT_TYPE_HTML } };
}
const middleware = async (request, locals) => {
emitViteBetterError = await import('../errors/create-vite-better-error.js').then(({ emitViteBetterError: e }) => e);
try {
const { url: requestedUrl, method } = request;
// MARK: Rewrite hidden route siblings

@@ -45,19 +42,18 @@ const fullUrl = requestedUrl.replace(/\/__(.*)$/, '/');

};
const routeInfos = await getRoute(routeOptions).catch(async (error) => {
// MARK: User defined Gracile 404 rewriting
logger.error(String(error));
const responseInit = {};
let routeInfos = await getRoute(routeOptions);
// MARK: 404
if (routeInfos === null) {
responseInit.status = 404;
const url = new URL('/404/', fullUrl).href;
const options = { ...routeOptions, url };
const notFound = await getRoute(options).catch((err) => err);
return notFound;
});
if (routeInfos instanceof Error) {
// MARK: Default, fallback 404
// const message = `404 not found!\n\n---\n\nCreate a /src/routes/404.{js,ts} to get a custom page.\n${method} - ${fullUrl}`;
const { errorPageHtml, headers } = await createErrorPage(fullUrl, routeInfos);
const notFound = await getRoute(options);
routeInfos = notFound;
}
// MARK: fallback 404
if (routeInfos === null) {
const page = builtIn404Page(new URL(fullUrl).pathname, Boolean(vite));
return {
response: new Response(errorPageHtml, {
headers,
status: 404,
statusText: '404 not found!',
response: new Response(await renderLitTemplate(page), {
headers: { ...CONTENT_TYPE_HTML },
}),

@@ -85,3 +81,2 @@ };

const handler = routeInfos.routeModule.handler;
const responseInit = {};
if (('handler' in routeInfos.routeModule &&

@@ -191,4 +186,2 @@ typeof handler !== 'undefined') ||

body: output.on('error', (error) => {
// NOTE: I think it's not usable here
// if (vite) vite.ssrFixStacktrace(error);
const errorMessage = `[SSR Error] There was an error while rendering a template chunk on server-side.\n` +

@@ -198,15 +191,23 @@ `It was omitted from the resulting HTML.\n`;

logger.error(errorMessage + error.stack);
// emitViteBetterError(new GracileError(GracileErrorData.FailedToGlobalLogger), vite);
const payload = {
type: 'error',
err: {
// FIXME: Use the emitViteBetterError instead (but flaky for now with streaming)
// @ts-expect-error ...........
err: new GracileError({
name: 'StreamingError',
title: 'An error occured during the page template streaming.',
message: errorMessage,
stack: error.stack ?? '',
plugin: 'gracile',
// NOTE: Other options seems to be unused by the overlay
},
hint: 'This is often caused by a wrong template location dynamic interpolation.',
// @ts-expect-error ...........
cause: error,
// highlightedCode: error.message,
}),
};
//
setTimeout(() => {
// @ts-expect-error ...........
vite.hot.send(payload);
// NOTE: Arbitrary value. Lower seems to be too fast, higher is not guaranteed to work.
}, 750);
}, 200);
}

@@ -223,10 +224,11 @@ else {

}
catch (e) {
const error = e;
if (vite)
vite.ssrFixStacktrace(error);
const { errorPageHtml: ultimateErrorPage, headers } = await createErrorPage('__gracile_error', error);
catch (error) {
// const safeError = createSafeError(error);
// TODO: User defined dev/runtime 500 error
const ultimateErrorPage = vite && emitViteBetterError
? await emitViteBetterError({ vite, error: error })
: await renderLitTemplate(builtInErrorPage(error.name));
return {
response: new Response(String(ultimateErrorPage), {
headers,
response: new Response(ultimateErrorPage, {
headers: { ...CONTENT_TYPE_HTML },
status: 500,

@@ -233,0 +235,0 @@ statusText: 'Gracile middleware error',

// NOTE: Util. to pretty print for user provided server.
import { env as currentEnv } from '@gracile/internal-utils/env';
import { logger } from '@gracile/internal-utils/logger';
import { getLogger } from '@gracile/internal-utils/logger/helpers';
import c from 'picocolors';

@@ -29,2 +29,3 @@ import { constants } from './constants.js';

export function printUrls(server) {
const logger = getLogger();
let address = null;

@@ -31,0 +32,0 @@ if (!server)

@@ -26,3 +26,4 @@ import { basename, extname, join } from 'node:path';

.replace(/index\.html$/, '__index.doc.html')
.replace(/404\.html$/, '__404.doc.html'));
.replace(/404\.html$/, '__404.doc.html')
.replace(/500\.html$/, '__500.doc.html'));
});

@@ -48,3 +49,3 @@ }

if (extname(id) === '.html') {
if (['index.html', '404.html'].includes(basename(id))) {
if (['index.html', '404.html', '500.html'].includes(basename(id))) {
const content = renderedRoutes.find((i) => i.absoluteId === id)?.html;

@@ -59,3 +60,4 @@ if (content)

.replace(/index\.html$/, '__index.doc.html')
.replace(/404\.html$/, '__404.doc.html') === id);
.replace(/404\.html$/, '__404.doc.html')
.replace(/500\.html$/, '__500.doc.html') === id);
})?.static.document;

@@ -62,0 +64,0 @@ if (content)

@@ -0,1 +1,2 @@

import { normalizeToPosix } from '@gracile/internal-utils/paths';
import { createFilter } from 'vite';

@@ -42,3 +43,3 @@ export function virtualRoutes({

${routesWithoutPrerender
.map(([pattern, route]) => `['${pattern}', () => import('/${route.filePath}')],`)
.map(([pattern, route]) => `['${pattern}', () => import('/${normalizeToPosix(route.filePath)}')],`)
.join('\n ')}

@@ -94,3 +95,3 @@ ]

? routes
.map(([pattern, route]) => `['${pattern}', () => import('/${route.filePath}')],`)
.map(([pattern, route]) => `['${pattern}', () => import('/${normalizeToPosix(route.filePath)}')],`)
.join('\n ')

@@ -97,0 +98,0 @@ : '/* DISABLED */'}

{
"name": "@gracile/engine",
"version": "0.7.0-next.0",
"version": "0.7.0-next.1",
"description": "A thin, full-stack, web framework",

@@ -46,7 +46,8 @@ "keywords": [

"dependencies": {
"@gracile-labs/better-errors": "^0.1.0-next.0",
"@gracile/client": "^0.3.1",
"@gracile/internal-utils": "^0.3.1",
"@gracile/internal-utils": "^0.4.0-next.0",
"@whatwg-node/server": "^0.9.25",
"fdir": "^6.2.0",
"picocolors": "^1.0.0",
"picocolors": "^1.0.1",
"urlpattern-polyfill": "^10.0.0",

@@ -77,3 +78,3 @@ "vite": "^5.3.5"

},
"gitHead": "ed69f4d4d482a43fdb12bc0a02f12093337d91c7"
"gitHead": "eb666d5de119a919c30846412cf3c5301200f9bd"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc