Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@ekino/rendr-loader

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ekino/rendr-loader - npm Package Compare versions

Comparing version 0.0.15 to 0.0.16

12

dist/_bundles/rendr-core.d.ts

@@ -24,3 +24,4 @@ declare module "types" {

declare module "index" {
import { Loader } from "types";
import { Loader, MaybePage } from "types";
import { Page, RendrError, RequestCtx } from "@ekino/rendr-core";
export * from "types";

@@ -30,3 +31,10 @@ export * from "services/inmemory";

export const createChainedLoader: (loaders: Loader[]) => Loader;
export const errorBoundaryLoader: Loader;
type Logger = Partial<{
log: (message?: any, ...optionalParams: any[]) => void;
error: (message?: any, ...optionalParams: any[]) => void;
warn: (message?: any, ...optionalParams: any[]) => void;
info: (message?: any, ...optionalParams: any[]) => void;
}>;
export function generateErrorHandler(logger: Logger): (err: RendrError | Error, ctx: RequestCtx, page: Page) => MaybePage;
export function createErrorBoundaryLoader(logger?: Logger): Loader;
}

77

dist/_bundles/rendr-core.js

@@ -68,5 +68,5 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

return function (ctx, page, next) { return __awaiter(_this, void 0, void 0, function () {
var result;
return __generator(this, function (_a) {
switch (_a.label) {
var result, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:

@@ -85,4 +85,5 @@ result = routes.find(function (conf) {

}
_a = next;
return [4, result.pageBuilder(ctx, page, function () { })];
case 1: return [2, _a.sent()];
case 1: return [2, _a.apply(void 0, [_b.sent()])];
}

@@ -232,23 +233,53 @@ });

};
exports.errorBoundaryLoader = function (ctx, page, next) { return __awaiter(void 0, void 0, void 0, function () {
var resultPage, err_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4, next()];
case 1:
resultPage = _a.sent();
return [3, 3];
case 2:
err_1 = _a.sent();
resultPage = rendr_core_3.createPage();
resultPage.statusCode = err_1 instanceof rendr_core_3.NotFoundError ? 404 : 500;
resultPage.settings.message = err_1.message;
return [3, 3];
case 3: return [2, resultPage];
function flattenStackTrace(err, stack) {
if (stack === void 0) { stack = []; }
if (err instanceof rendr_core_3.RendrError && err.previousError) {
flattenStackTrace(err.previousError, stack);
}
stack.push(err.stack);
return stack;
}
function generateErrorHandler(logger) {
return function (err, ctx, page) {
var fullStack = flattenStackTrace(err);
fullStack.forEach(function (stack) { return logger.log(stack); });
if (ctx.res && ctx.res.headersSent) {
ctx.res.end();
return;
}
});
}); };
var resultPage = rendr_core_3.createPage();
resultPage.statusCode = err instanceof rendr_core_3.NotFoundError ? 404 : 500;
resultPage.settings.message = err.message;
if (ctx.isServerSide && process.env.NODE_ENV !== "production") {
resultPage.settings.stackTrace = fullStack;
}
if (ctx.isClientSide) {
throw err;
}
return resultPage;
};
}
exports.generateErrorHandler = generateErrorHandler;
function createErrorBoundaryLoader(logger) {
var _this = this;
if (logger === void 0) { logger = console; }
return function (ctx, page, next) { return __awaiter(_this, void 0, void 0, function () {
var err_1, handler;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4, next()];
case 1: return [2, _a.sent()];
case 2:
err_1 = _a.sent();
handler = generateErrorHandler(logger);
return [2, handler(err_1, ctx, page)];
case 3: return [2];
}
});
}); };
}
exports.createErrorBoundaryLoader = createErrorBoundaryLoader;
});
//# sourceMappingURL=rendr-core.js.map

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

import { Loader } from "./types";
import { Loader, MaybePage } from "./types";
import { Page, RendrError, RequestCtx } from "@ekino/rendr-core";
export * from "./types";

@@ -6,2 +7,9 @@ export * from "./services/inmemory";

export declare const createChainedLoader: (loaders: Loader[]) => Loader;
export declare const errorBoundaryLoader: Loader;
declare type Logger = Partial<{
log: (message?: any, ...optionalParams: any[]) => void;
error: (message?: any, ...optionalParams: any[]) => void;
warn: (message?: any, ...optionalParams: any[]) => void;
info: (message?: any, ...optionalParams: any[]) => void;
}>;
export declare function generateErrorHandler(logger: Logger): (err: RendrError | Error, ctx: RequestCtx, page: Page) => MaybePage;
export declare function createErrorBoundaryLoader(logger?: Logger): Loader;

@@ -37,3 +37,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

};
import { Page, createPage, NotFoundError } from "@ekino/rendr-core";
import { Page, createPage, NotFoundError, RendrError } from "@ekino/rendr-core";
export * from "./services/inmemory";

@@ -75,22 +75,50 @@ export * from "./services/api";

};
export var errorBoundaryLoader = function (ctx, page, next) { return __awaiter(void 0, void 0, void 0, function () {
var resultPage, err_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4, next()];
case 1:
resultPage = _a.sent();
return [3, 3];
case 2:
err_1 = _a.sent();
resultPage = createPage();
resultPage.statusCode = err_1 instanceof NotFoundError ? 404 : 500;
resultPage.settings.message = err_1.message;
return [3, 3];
case 3: return [2, resultPage];
function flattenStackTrace(err, stack) {
if (stack === void 0) { stack = []; }
if (err instanceof RendrError && err.previousError) {
flattenStackTrace(err.previousError, stack);
}
stack.push(err.stack);
return stack;
}
export function generateErrorHandler(logger) {
return function (err, ctx, page) {
var fullStack = flattenStackTrace(err);
fullStack.forEach(function (stack) { return logger.log(stack); });
if (ctx.res && ctx.res.headersSent) {
ctx.res.end();
return;
}
});
}); };
var resultPage = createPage();
resultPage.statusCode = err instanceof NotFoundError ? 404 : 500;
resultPage.settings.message = err.message;
if (ctx.isServerSide && process.env.NODE_ENV !== "production") {
resultPage.settings.stackTrace = fullStack;
}
if (ctx.isClientSide) {
throw err;
}
return resultPage;
};
}
export function createErrorBoundaryLoader(logger) {
var _this = this;
if (logger === void 0) { logger = console; }
return function (ctx, page, next) { return __awaiter(_this, void 0, void 0, function () {
var err_1, handler;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4, next()];
case 1: return [2, _a.sent()];
case 2:
err_1 = _a.sent();
handler = generateErrorHandler(logger);
return [2, handler(err_1, ctx, page)];
case 3: return [2];
}
});
}); };
}
//# sourceMappingURL=index.js.map

@@ -59,5 +59,5 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

return function (ctx, page, next) { return __awaiter(_this, void 0, void 0, function () {
var result;
return __generator(this, function (_a) {
switch (_a.label) {
var result, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:

@@ -76,4 +76,5 @@ result = routes.find(function (conf) {

}
_a = next;
return [4, result.pageBuilder(ctx, page, function () { })];
case 1: return [2, _a.sent()];
case 1: return [2, _a.apply(void 0, [_b.sent()])];
}

@@ -80,0 +81,0 @@ });

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

import { Loader } from "./types";
import { Loader, MaybePage } from "./types";
import { Page, RendrError, RequestCtx } from "@ekino/rendr-core";
export * from "./types";

@@ -6,2 +7,9 @@ export * from "./services/inmemory";

export declare const createChainedLoader: (loaders: Loader[]) => Loader;
export declare const errorBoundaryLoader: Loader;
declare type Logger = Partial<{
log: (message?: any, ...optionalParams: any[]) => void;
error: (message?: any, ...optionalParams: any[]) => void;
warn: (message?: any, ...optionalParams: any[]) => void;
info: (message?: any, ...optionalParams: any[]) => void;
}>;
export declare function generateErrorHandler(logger: Logger): (err: RendrError | Error, ctx: RequestCtx, page: Page) => MaybePage;
export declare function createErrorBoundaryLoader(logger?: Logger): Loader;

@@ -79,22 +79,52 @@ "use strict";

};
exports.errorBoundaryLoader = function (ctx, page, next) { return __awaiter(void 0, void 0, void 0, function () {
var resultPage, err_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4, next()];
case 1:
resultPage = _a.sent();
return [3, 3];
case 2:
err_1 = _a.sent();
resultPage = rendr_core_1.createPage();
resultPage.statusCode = err_1 instanceof rendr_core_1.NotFoundError ? 404 : 500;
resultPage.settings.message = err_1.message;
return [3, 3];
case 3: return [2, resultPage];
function flattenStackTrace(err, stack) {
if (stack === void 0) { stack = []; }
if (err instanceof rendr_core_1.RendrError && err.previousError) {
flattenStackTrace(err.previousError, stack);
}
stack.push(err.stack);
return stack;
}
function generateErrorHandler(logger) {
return function (err, ctx, page) {
var fullStack = flattenStackTrace(err);
fullStack.forEach(function (stack) { return logger.log(stack); });
if (ctx.res && ctx.res.headersSent) {
ctx.res.end();
return;
}
});
}); };
var resultPage = rendr_core_1.createPage();
resultPage.statusCode = err instanceof rendr_core_1.NotFoundError ? 404 : 500;
resultPage.settings.message = err.message;
if (ctx.isServerSide && process.env.NODE_ENV !== "production") {
resultPage.settings.stackTrace = fullStack;
}
if (ctx.isClientSide) {
throw err;
}
return resultPage;
};
}
exports.generateErrorHandler = generateErrorHandler;
function createErrorBoundaryLoader(logger) {
var _this = this;
if (logger === void 0) { logger = console; }
return function (ctx, page, next) { return __awaiter(_this, void 0, void 0, function () {
var err_1, handler;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4, next()];
case 1: return [2, _a.sent()];
case 2:
err_1 = _a.sent();
handler = generateErrorHandler(logger);
return [2, handler(err_1, ctx, page)];
case 3: return [2];
}
});
}); };
}
exports.createErrorBoundaryLoader = createErrorBoundaryLoader;
//# sourceMappingURL=index.js.map

@@ -64,5 +64,5 @@ "use strict";

return function (ctx, page, next) { return __awaiter(_this, void 0, void 0, function () {
var result;
return __generator(this, function (_a) {
switch (_a.label) {
var result, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:

@@ -81,4 +81,5 @@ result = routes.find(function (conf) {

}
_a = next;
return [4, result.pageBuilder(ctx, page, function () { })];
case 1: return [2, _a.sent()];
case 1: return [2, _a.apply(void 0, [_b.sent()])];
}

@@ -85,0 +86,0 @@ });

{
"name": "@ekino/rendr-loader",
"license": "MIT",
"version": "0.0.15",
"version": "0.0.16",
"main": "dist/lib/index.js",

@@ -13,3 +13,3 @@ "typing": "dist/lib/index.d.ts",

"dependencies": {
"@ekino/rendr-core": "0.0.15",
"@ekino/rendr-core": "0.0.16",
"axios": "^0.19.0",

@@ -26,3 +26,3 @@ "path-match": "^1.2.4",

},
"gitHead": "5c773d43e512291a844b999855ee6d6b23b0cc79"
"gitHead": "42720e423cf54b2976e74fe476d588c891becb91"
}

@@ -1,5 +0,8 @@

import { createChainedLoader } from "./index";
import { createChainedLoader, createErrorBoundaryLoader } from "./index";
import { Page, RequestCtx } from "@ekino/rendr-core";
import { Loader } from "./types";
const logger = { log: jest.fn() };
const errorBoundaryLoader = createErrorBoundaryLoader(logger);
let mainPage: Page;

@@ -11,6 +14,12 @@ let witnessPage: Page;

// @ts-ignore
res: jest.fn(),
res: {
statusCode: 200,
end: jest.fn()
},
isServerSide: true,
isClientSide: false,
pathname: "/",
query: {},
asPath: "/"
asPath: "/",
settings: {}
};

@@ -40,7 +49,7 @@

page.head.title = "block execution of the next loaders";
console.log("No call to the next function");
// console.log("No call to the next function");
};
const exitingLoader: Loader = (ctx, page, next) => {
console.log("Return a page object");
// console.log("Return a page object");
return witnessPage;

@@ -50,3 +59,3 @@ };

const referenceChangeLoader: Loader = (ctx, page, next) => {
console.log("Pass a new page to the next loader");
// console.log("Pass a new page to the next loader");
return next(witnessPage);

@@ -56,3 +65,3 @@ };

const resultPageNullifierLoader: Loader = (ctx, page, next) => {
console.log("Call next but do not return it");
// console.log("Call next but do not return it");
next();

@@ -66,2 +75,4 @@ };

witnessPage.head.title = "witness";
ctx.isServerSide = true;
ctx.isClientSide = false;
});

@@ -132,1 +143,81 @@

});
describe("test errorBoundaryLoader", () => {
it("should return the page reference given to it if no error", async () => {
const loader = createChainedLoader([errorBoundaryLoader, loader1]);
const resultPage = await loader(ctx, mainPage, () => {});
expect(mainPage.head.title).toEqual("main");
expect(mainPage.blocks.length).toEqual(1);
expect(mainPage.blocks[0].type).toEqual("block1");
expect(resultPage).toEqual(mainPage);
});
it("should catch errors and return a new page instance", async () => {
const loader = createChainedLoader([
errorBoundaryLoader,
(context, page, next) => {
throw new Error("An error");
}
]);
const resultPage = await loader(ctx, mainPage, () => {});
// @ts-ignore
expect(resultPage.statusCode).toEqual(500);
// @ts-ignore
expect(resultPage.settings.message).toEqual("An error");
expect(resultPage).not.toEqual(mainPage);
});
it("should still throw the exception when client side", async () => {
const loader = createChainedLoader([
errorBoundaryLoader,
(context, page, next) => {
throw new Error("An error");
}
]);
ctx.isServerSide = false;
ctx.isClientSide = true;
let witnessError;
try {
const resultPage = await loader(ctx, mainPage, () => {});
} catch (err) {
witnessError = err;
}
// @ts-ignore
expect(witnessError).toBeInstanceOf(Error);
});
it("should not return the stack trace in the page when in production mode", async () => {
const loader = createChainedLoader([
errorBoundaryLoader,
(context, page, next) => {
throw new Error("An error");
}
]);
const oldEnv = process.env.NODE_ENV;
process.env.NODE_ENV = "production";
const resultPage = await loader(ctx, mainPage, () => {});
// @ts-ignore
expect(resultPage.settings.message).toEqual("An error");
// @ts-ignore
expect(resultPage.settings.stackTrace).toBeUndefined();
process.env.NODE_ENV = oldEnv;
});
it("should call response end if headers have been sent", async () => {
const loader = createChainedLoader([
errorBoundaryLoader,
(context, page, next) => {
context.res.headersSent = true;
throw new Error("An error");
}
]);
const resultPage = await loader(ctx, mainPage, () => {});
// @ts-ignore
expect(resultPage).toBeUndefined();
// @ts-ignore
expect(ctx.res.end).toHaveBeenCalled();
});
});

@@ -1,3 +0,10 @@

import { Loader } from "./types";
import { Page, createPage, NotFoundError } from "@ekino/rendr-core";
import { Loader, MaybePage } from "./types";
import {
Page,
createPage,
NotFoundError,
RendrError,
RequestCtx
} from "@ekino/rendr-core";
import { type } from "os";

@@ -31,15 +38,61 @@ export * from "./types";

// Simple version of a loader that catches errors during the execution of
// following loaders
// Feel free to use your own if you want to manage other error codes
export const errorBoundaryLoader: Loader = async (ctx, page, next) => {
let resultPage: Page | void;
try {
resultPage = await next();
} catch (err) {
resultPage = createPage();
function flattenStackTrace(err: Error | RendrError, stack: string[] = []) {
if (err instanceof RendrError && err.previousError) {
flattenStackTrace(err.previousError, stack);
}
stack.push(err.stack);
return stack;
}
type Logger = Partial<{
log: (message?: any, ...optionalParams: any[]) => void;
error: (message?: any, ...optionalParams: any[]) => void;
warn: (message?: any, ...optionalParams: any[]) => void;
info: (message?: any, ...optionalParams: any[]) => void;
}>;
// Behaviour is as follow:
// 1. Always log the error stack
// 2. If headers were sent, just ends the response
// 3. The resultPage receives the message of the error in the key message of its settings
// 4. In non production mode, resultPage also receives the error trace
// 5. Client side, the error is thrown as normal for browser to catch it
export function generateErrorHandler(logger: Logger) {
return (err: Error | RendrError, ctx: RequestCtx, page: Page): MaybePage => {
const fullStack = flattenStackTrace(err);
fullStack.forEach(stack => logger.log(stack));
if (ctx.res && ctx.res.headersSent) {
ctx.res.end();
return;
}
const resultPage = createPage();
resultPage.statusCode = err instanceof NotFoundError ? 404 : 500;
resultPage.settings.message = err.message;
}
return resultPage;
};
if (ctx.isServerSide && process.env.NODE_ENV !== "production") {
resultPage.settings.stackTrace = fullStack;
}
if (ctx.isClientSide) {
throw err;
}
return resultPage;
};
}
export function createErrorBoundaryLoader(logger: Logger = console): Loader {
return async (ctx, page, next) => {
try {
return await next();
} catch (err) {
const handler = generateErrorHandler(logger);
return handler(err, ctx, page);
}
};
}

@@ -86,6 +86,3 @@ import { createPage, Page } from "@ekino/rendr-core";

return pipe(
response.data,
ctx.res
);
return pipe(response.data, ctx.res);
}

@@ -134,8 +131,5 @@ }

return pipe(
source,
dest
).then(() => {
return pipe(source, dest).then(() => {
return createPage(JSON.parse(data));
});
}

@@ -50,4 +50,4 @@ import { NotFoundError } from "@ekino/rendr-core";

return await result.pageBuilder(ctx, page, () => {});
return next(await result.pageBuilder(ctx, page, () => {}));
};
}

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