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

kwyjibo

Package Overview
Dependencies
Maintainers
2
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

kwyjibo - npm Package Compare versions

Comparing version 1.0.1 to 1.0.3

6

js/controller.d.ts

@@ -129,2 +129,7 @@ import * as Express from "express";

}
export declare class KwyjiboControllerTreeNode {
controller: KwyjiboController;
childs: KwyjiboControllerTreeNode[];
constructor(controller: KwyjiboController);
}
export declare type KwyjiboControllerMap = {

@@ -140,2 +145,3 @@ [key: string]: KwyjiboController;

mountpoints: KwyjiboMountpoint[];
controllersTree: KwyjiboControllerTreeNode[];
getController(ctr: Function): KwyjiboController;

@@ -142,0 +148,0 @@ getOrInsertController(ctr: Function): KwyjiboController;

123

js/controller.js

@@ -12,2 +12,3 @@ "use strict";

const U = require("./utils");
const T = require("./testing");
/**

@@ -243,2 +244,9 @@ * Contains context for the current call .

exports.KwyjiboController = KwyjiboController;
class KwyjiboControllerTreeNode {
constructor(controller) {
this.childs = [];
this.controller = controller;
}
}
exports.KwyjiboControllerTreeNode = KwyjiboControllerTreeNode;
class KwyjiboControllersState {

@@ -248,2 +256,3 @@ constructor() {

this.mountpoints = [];
this.controllersTree = [];
}

@@ -268,3 +277,41 @@ getController(ctr) {

exports.globalKCState = new KwyjiboControllersState();
function mountMethod(controller, instance, methodKey, method) {
function addChildsToTreeNode(node) {
for (let mp of exports.globalKCState.mountpoints) {
if (node.controller.ctr.toString() === mp.dstCtr.toString()) {
let child = new KwyjiboControllerTreeNode(exports.globalKCState.getController(mp.ctr));
addChildsToTreeNode(child);
node.childs.push(child);
}
}
}
function buildControllersTree() {
for (let ck in exports.globalKCState.controllers) {
let c = exports.globalKCState.controllers[ck];
if (c.childController === false) {
let node = new KwyjiboControllerTreeNode(c);
addChildsToTreeNode(node);
exports.globalKCState.controllersTree.push(node);
}
}
}
function indexAutogenerator(controller, childs) {
return (req, res) => {
let content = "<html><head></head><body><pre> Autogenerated Index (Only in dev env) <br /><br />";
for (let child of childs) {
content += `[Controller] <a href=".${child.controller.path}/">${child.controller.path}</a><br />`;
}
content += "<br />";
if (controller != undefined) {
for (let mk in controller.methods) {
for (let mmp of controller.methods[mk].methodMountpoints) {
content += `[${mmp.httpMethod.toUpperCase()}] <a href=".${mmp.path}/">${mmp.path}</a><br />`;
}
}
}
content += "</pre></body></html>";
res.send(content);
};
}
function mountMethod(controller, instance, methodKey) {
let method = controller.methods[methodKey];
if (method.explicitlyDeclared === false) {

@@ -276,5 +323,5 @@ U.defaultWarn(`Method ${methodKey} was not explicitaly declared with a decorator. Defaulting to GET@/${methodKey}`);

let callback = (req, res, next) => {
let context = new Context();
let runner = () => __awaiter(this, void 0, void 0, function* () {
let ret;
let context = new Context();
if (method.expressCompatible) {

@@ -298,29 +345,25 @@ ret = instance[methodKey](req, res, next);

}
context.dispose();
});
runner().catch((err) => { next(err); });
runner().then(() => { context.dispose(); })
.catch((err) => { context.dispose(); next(err); });
};
controller.router[mp.httpMethod](mp.path, ...method.middleware, callback);
controller.router[mp.httpMethod](U.UrlJoin(mp.path, "/"), ...method.middleware, callback);
}
}
function indexAutogenerator(mountpoint, childControllerPaths) {
return (req, res) => {
let content = "<html><head></head><body><pre> Autogenerated Index (Only in dev env) <br /><br />";
let curPath = (mountpoint instanceof KwyjiboController) ? mountpoint.path : mountpoint;
for (let child of childControllerPaths) {
content += `[Controller] <a href="${U.UrlJoin("/", curPath, child).substr(1)}">${child}</a><br />`;
function useRouterAtPathStrict(baseRouter, basePath, router) {
if (basePath.substring(basePath.length - 1) === "/") {
basePath = basePath.substr(0, basePath.length - 1);
}
let strictPath = U.UrlJoin(basePath, "/");
baseRouter.use(strictPath, (req, res, next) => {
if (req.originalUrl.substring(req.originalUrl.length - basePath.length) === basePath) {
res.redirect(strictPath);
}
content += "<br />";
if (mountpoint instanceof KwyjiboController) {
for (let mk in mountpoint.methods) {
for (let mmp of mountpoint.methods[mk].methodMountpoints) {
content += `[${mmp.httpMethod.toUpperCase()}] <a href="${U.UrlJoin("/", curPath, mmp.path).substr(1)}">${mmp.path}</a><br />`;
}
}
else {
next();
}
content += "</pre></body></html>";
res.send(content);
};
}, router);
}
function addControllerRecursive(app, controller) {
function createRouterRecursive(app, controllerNode) {
let controller = controllerNode.controller;
if (controller.mountCondition === false) {

@@ -338,16 +381,15 @@ return undefined;

for (let mk in controller.methods) {
mountMethod(controller, instance, mk, controller.methods[mk]);
mountMethod(controller, instance, mk);
}
let childControllerPaths = [];
for (let mp of exports.globalKCState.mountpoints) {
if (controller.ctr.toString() === mp.dstCtr.toString()) {
let nc = addControllerRecursive(app, exports.globalKCState.getController(mp.ctr));
if (nc != undefined) {
controller.router.use(nc.path, nc.router);
childControllerPaths.push(nc.path);
}
for (let child of controllerNode.childs) {
let nc = createRouterRecursive(app, child);
if (nc != undefined) {
useRouterAtPathStrict(controller.router, nc.path, nc.router);
}
}
if (controller.generateTestRunnerPaths) {
T.injectTestRunnerMiddleware(controller);
}
if (process.env.NODE_ENV === "development") {
controller.router.get("/", indexAutogenerator(controller, childControllerPaths));
controller.router.get("/", indexAutogenerator(controller, controllerNode.childs));
}

@@ -358,18 +400,13 @@ return controller;

rootPath = rootPath || "/";
//A method without paths, defaults to get with the name of the method as path
let childControllerPaths = [];
for (let ck in exports.globalKCState.controllers) {
let c = exports.globalKCState.controllers[ck];
if (c.childController === false) {
let nc = addControllerRecursive(app, c);
if (nc != undefined) {
app.use(U.UrlJoin(rootPath, nc.path), nc.router);
childControllerPaths.push(nc.path);
}
buildControllersTree();
for (let node of exports.globalKCState.controllersTree) {
let nc = createRouterRecursive(app, node);
if (nc != undefined) {
useRouterAtPathStrict(app, U.UrlJoin(rootPath, nc.path), nc.router);
}
}
if (process.env.NODE_ENV === "development") {
app.get(rootPath, indexAutogenerator(rootPath, childControllerPaths));
app.get(rootPath, indexAutogenerator(undefined, exports.globalKCState.controllersTree));
}
}
exports.addControllersToExpressApp = addControllersToExpressApp;

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

export * from './controller';
export * from './testing';
export * from './utils';
export * from "./controller";
export * from "./testing";
export * from "./utils";

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

}
__export(require('./controller'));
__export(require('./testing'));
__export(require('./utils'));
__export(require("./controller"));
__export(require("./testing"));
__export(require("./utils"));

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

import * as C from "./controller";
/*********************************************************

@@ -47,6 +48,19 @@ * Class Decorators

};
export declare class KwyjiboTestResult {
fixtureDesc: string;
fixtureKey: string;
testDesc: string;
testKey: string;
passed: boolean;
message: string;
}
export declare class KwyjiboTestsState {
fixtures: KwyjiboFixtureMap;
getOrInsertFixture(ctr: Function): KwyjiboFixture;
generateCompleteFixtureMetadata(): Object;
static getFixtureHashId(fixture: KwyjiboFixture): string;
generateRainbowTables(): Object;
run(testsToRun?: Object): Promise<KwyjiboTestResult[]>;
}
export declare let globalKTState: KwyjiboTestsState;
export declare function injectTestRunnerMiddleware(controller: C.KwyjiboController): void;

@@ -0,5 +1,15 @@

"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments)).next());
});
};
const Crypto = require("crypto");
const U = require("./utils");
/*********************************************************
* Class Decorators
*********************************************************/
"use strict";
/**

@@ -75,2 +85,5 @@ * Registers a fixture of tests with the global test runner.

exports.KwyjiboFixture = KwyjiboFixture;
class KwyjiboTestResult {
}
exports.KwyjiboTestResult = KwyjiboTestResult;
class KwyjiboTestsState {

@@ -88,4 +101,310 @@ constructor() {

}
generateCompleteFixtureMetadata() {
let metadata = {};
for (let fxk in this.fixtures) {
let fixture = this.fixtures[fxk];
let fxkHash = KwyjiboTestsState.getFixtureHashId(fixture);
metadata[fxkHash] = {};
for (let tk in fixture.tests) {
metadata[fxkHash][tk] = true;
}
}
return metadata;
}
static getFixtureHashId(fixture) {
let hasher = Crypto.createHash("sha256");
hasher.update(fixture.ctr.toString());
return fixture.ctr.name + "_" + hasher.digest("hex").substr(0, 8);
}
generateRainbowTables() {
let rt = {};
for (let fxk in this.fixtures) {
let fixture = this.fixtures[fxk];
let fxkHash = KwyjiboTestsState.getFixtureHashId(fixture);
rt[fxkHash] = fixture;
}
return rt;
}
run(testsToRun) {
return __awaiter(this, void 0, Promise, function* () {
if (testsToRun == undefined) {
testsToRun = this.generateCompleteFixtureMetadata();
}
let testResults = [];
let rainbowTables = this.generateRainbowTables();
for (let fxk in testsToRun) {
let fixture = rainbowTables[fxk];
let fi = Reflect.construct(fixture.ctr, []);
for (let mn of fixture.runBeforeMethods) {
let r = fi[mn]();
if (r instanceof Promise) {
yield r;
}
}
for (let mn in testsToRun[fxk]) {
if (testsToRun[fxk][mn] === true && fixture.tests[mn] != undefined && fi[mn] != undefined) {
let result = new KwyjiboTestResult();
result.fixtureKey = fxk;
result.fixtureDesc = fixture.humanReadableName;
result.testKey = mn;
result.testDesc = fixture.tests[mn].humanReadableName;
try {
let r = fi[mn]();
if (r instanceof Promise) {
yield r;
}
result.passed = true;
result.message = "";
}
catch (err) {
result.passed = false;
if (err instanceof Error) {
result.message = JSON.stringify({ name: err.name, message: err.message, stack: err.stack });
}
else if (err instanceof Object) {
result.message = JSON.stringify(err);
}
else if (typeof (err) === "string") {
result.message = err;
}
else {
result.message = err.toString();
}
}
testResults.push(result);
}
}
for (let mn of fixture.runAfterMethods) {
let r = fi[mn]();
if (r instanceof Promise) {
yield r;
}
}
}
return testResults;
});
}
}
exports.KwyjiboTestsState = KwyjiboTestsState;
exports.globalKTState = new KwyjiboTestsState();
const defaultCSS = `
body {
font-family:verdana;
}
tr {
padding:5px;
}
tr a {
color:#000000;
}
tr.header {
background-color:#AAAAAA;
}
tr.header-allpassed {
background-color:#00AA00;
}
tr.header-somefailed {
background-color:#AA0000;
}
tr.header-somefailed a{
color:#FFFFFF;
}
button#runButton {
width:100%;
font-size:18px;
font-weight:bold;
}
.flex-container {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: flex-start;
align-content: stretch;
align-items: center;
}
.flex-item {
order: 0;
flex: 0 1 auto;
align-self: auto;
}
`;
function generateInteractiveTestRunnerMiddleware(useFixture) {
return (req, res) => {
let content = `
<html>
<head>
<style>
${defaultCSS}
</style>
</head>
<body class="flex-container">
<script>
function init() {
var runners = Array.from(document.querySelectorAll('input.runner'));
runners.forEach(function(runner){
runner.onchange = function(e) {
var childs = Array.from(document.querySelectorAll('input.' + e.target.id));
childs.forEach(function(child){
child.checked = e.target.checked;
});
};
});
document.getElementById('runButton').onclick=submit;
}
function submit() {
var runners = Array.from(document.querySelectorAll('input.runner'));
var toSubmit = {};
runners.forEach(function(runner){
document.getElementById(runner.id+"-header").className="header";
var childs = Array.from(document.querySelectorAll('input.' + runner.id));
childs.forEach(function(child){
var curTD = document.getElementById(runner.id+"_"+child.id+"_result");
if(child.checked) {
if(toSubmit[runner.id]==undefined) toSubmit[runner.id]={};
toSubmit[runner.id][child.id]=true;
curTD.innerHTML="&#x1f552;";
curTD.title="Loading...";
} else {
curTD.innerHTML="";
curTD.title="";
}
});
});
var xhr = new XMLHttpRequest();
xhr.open("POST", "${useFixture == undefined ? "" : "../../"}some", true);
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
// send the collected data as JSON
xhr.send(JSON.stringify(toSubmit));
xhr.onloadend = function () {
var results = JSON.parse(this.responseText);
var fixturePass = {};
results.forEach(function(result){
if(fixturePass[result.fixtureKey]==undefined) {
fixturePass[result.fixtureKey]=true;
}
var rTD = document.getElementById(result.fixtureKey+"_"+result.testKey+"_result");
rTD.innerHTML = result.passed ? '&#x2705;' : '&#x274c;';
if(!result.passed) {
fixturePass[result.fixtureKey]=false;
}
rTD.title = result.message;
});
for(var fxk in fixturePass) {
var fh = document.getElementById(fxk+"-header");
fh.className = fixturePass[fxk]? "header-allpassed" : "header-somefailed";
}
};
}
window.onload=init;
</script>
<div class="flex-item">
<center>
<h2> Interactive Tests Runner </h2>
`;
let useFixtureHash = undefined;
if (useFixture == undefined) {
content += `
To run all the tests programatically use: <a href="all">/all</a><br />
To run some of the tests programatically send a JSON payload via POST to: <a href="some">/some</a><br />
(You can see how the JSON payload should look at <a href="metadata">/metadata</a>)<br /><br />
`;
}
else {
content += `
To run all the tests programatically use: <a href="all">/all</a><br />
To run some of the tests programatically, see <a href="../../">tests home</a><br /><br />
`;
useFixtureHash = KwyjiboTestsState.getFixtureHashId(useFixture);
}
content += `<table>`;
for (let fxk in exports.globalKTState.fixtures) {
let fixture = exports.globalKTState.fixtures[fxk];
let fxkHash = KwyjiboTestsState.getFixtureHashId(fixture);
if (useFixtureHash != undefined && fxkHash !== useFixtureHash) {
continue;
}
content += `<tr class="header" id="${fxkHash}-header" >
<td><input class="runner" id="${fxkHash}" type="checkbox" checked /></td>
<td colspan="2"><a href="fixture/${fxkHash}/">${fixture.humanReadableName}</a></td></tr>`;
for (let tk in fixture.tests) {
let test = fixture.tests[tk];
content += `<tr><td><input class="${fxkHash}" id="${tk}" type="checkbox" checked /></td>
<td text-align="left">${test.humanReadableName}</td><td id="${fxkHash}_${tk}_result"></td></tr>`;
}
}
content += `<tr><td colspan="3"></td></tr><tr><td colspan="3"><button id="runButton">Run Tests</button></td></tr>`;
content += "</table>";
content += "</center></div></body></html>";
res.send(content);
};
}
function runSetOfTestsAndFillResponse(testsToRun, res) {
return __awaiter(this, void 0, Promise, function* () {
let results = yield exports.globalKTState.run(testsToRun);
let failed = false;
for (let result of results) {
if (result.passed === false) {
failed = true;
}
}
res.statusCode = failed ? 418 : 200;
res.json(results);
});
}
function injectTestRunnerMiddleware(controller) {
/*
Available endpoints:
- /: interactive shell
- /all: run all tests unattended
- /metadata: get json metadata for available tests.
- /some: post a json to run only a subset of tests.
- /fixture/[FixtureName]: link to all tests in fixture (interactive shell)
- /fixture/[FixtureName]/all
*/
controller.router.get("/all", (req, res) => __awaiter(this, void 0, void 0, function* () {
yield runSetOfTestsAndFillResponse(undefined, res);
}));
controller.router.post("/some", (req, res) => __awaiter(this, void 0, void 0, function* () {
yield runSetOfTestsAndFillResponse(req.body, res);
}));
controller.router.get("/metadata", (req, res) => {
res.json(exports.globalKTState.generateCompleteFixtureMetadata());
});
for (let fxk in exports.globalKTState.fixtures) {
let fixture = exports.globalKTState.fixtures[fxk];
let fxkHash = KwyjiboTestsState.getFixtureHashId(fixture);
controller.router.get(U.UrlJoin("/fixture/", fxkHash, "/"), generateInteractiveTestRunnerMiddleware(fixture));
controller.router.get(U.UrlJoin("/fixture/", fxkHash, "/all"), (req, res) => __awaiter(this, void 0, void 0, function* () {
let metadata = exports.globalKTState.generateCompleteFixtureMetadata();
let thisFixtureSet = {};
for (let mk in metadata) {
if (mk === fxkHash) {
thisFixtureSet[mk] = metadata[mk];
}
}
yield runSetOfTestsAndFillResponse(thisFixtureSet, res);
}));
}
controller.router.get("/", generateInteractiveTestRunnerMiddleware());
}
exports.injectTestRunnerMiddleware = injectTestRunnerMiddleware;
{
"name": "kwyjibo",
"version": "1.0.1",
"version": "1.0.3",
"description": "A set of Typescript Decorators and helpers to write better node.js+Express applications.",

@@ -5,0 +5,0 @@ "main": "js/index.js",

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