Compare commits
60 Commits
89a861a2dd
...
master
Author | SHA1 | Date | |
---|---|---|---|
5d9f4754a5 | |||
2cac260954 | |||
d298b8e842 | |||
bd63607477 | |||
55d461fb8e | |||
895893e76a | |||
39fbc73c74 | |||
e1c26e2c5e | |||
d3a93108e2 | |||
7a79aca59b | |||
ffb086a774 | |||
d1499bb6d4 | |||
a6d4a35588 | |||
2e4bb21354 | |||
3ed5253fc4 | |||
274f2b4b7a | |||
6eae1742d6 | |||
cc59df51d0 | |||
2a950310be | |||
9b4ad340a2 | |||
dfc0bc3b7e | |||
c2ea65a992 | |||
3de5485650 | |||
dfd3df544c | |||
7fe6dee81c | |||
1d7791c2b0 | |||
3c8dcf3ad2 | |||
ab70c46501 | |||
3af8b97258 | |||
431e21806b | |||
1541018701 | |||
0eea261e56 | |||
00546001eb | |||
db3ae308e6 | |||
20394e65f8 | |||
7b9ce83c71 | |||
fccd69db74 | |||
95814c5541 | |||
27cec2cb0b | |||
3716e80674 | |||
3b9e3d416a | |||
8b8fbb3ec5 | |||
374940757a | |||
228c204255 | |||
a1715aa117 | |||
c053340e5e | |||
a208a2fb50 | |||
52597ca46f | |||
efa44f0405 | |||
2dc969a47d | |||
bc50897afc | |||
64ec1b5db5 | |||
999d493c68 | |||
1a98e86954 | |||
7a9e12e62d | |||
ce4e78e0d5 | |||
bda39f279f | |||
111df45892 | |||
bff13c3364 | |||
6f242fb79f |
@ -2,7 +2,7 @@
|
||||
* Copyright (C) Sapphirecode - All Rights Reserved
|
||||
* This file is part of Requestor which is released under BSD-3-Clause.
|
||||
* See file 'LICENSE' for full license details.
|
||||
* Created by Timo Hocker <timo@scode.ovh>, March 2020
|
||||
* Created by Timo Hocker <timo@sapphirecode.ovh>, March 2020
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
@ -12,6 +12,6 @@ module.exports = {
|
||||
node: true
|
||||
},
|
||||
extends: [
|
||||
'@scode'
|
||||
'@sapphirecode'
|
||||
]
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
/test/
|
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@ -5,7 +5,7 @@ pipeline {
|
||||
VERSION = VersionNumber([
|
||||
versionNumberString:
|
||||
'${BUILDS_ALL_TIME}',
|
||||
versionPrefix: '1.1.',
|
||||
versionPrefix: '2.0.',
|
||||
worstResultForIncrement: 'SUCCESS'
|
||||
])
|
||||
}
|
||||
|
121
dist/index.js
vendored
121
dist/index.js
vendored
@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Sapphirecode - All Rights Reserved
|
||||
* This file is part of Requestor which is released under BSD-3-Clause.
|
||||
* See file 'LICENSE' for full license details.
|
||||
* Created by Timo Hocker <timo@scode.ovh>, March 2020
|
||||
*/
|
||||
/* eslint-disable no-console */
|
||||
/* eslint-disable no-sync */
|
||||
'use strict';
|
||||
const fs = require ('fs');
|
||||
const path = require ('path');
|
||||
|
||||
/**
|
||||
* @typedef {object} options
|
||||
* @property {any} [opts] object to pass to the handlers
|
||||
* @property {string} [subdir] subdirectory for all requests
|
||||
* @property {boolean} [verbose] enable verbose logging
|
||||
* @property {boolean} [rethrow] rethrow errors (default: true)
|
||||
*/
|
||||
/**
|
||||
* @typedef {object} handler_description
|
||||
* @property {string} module_folder folder the module file is in
|
||||
* @property {string} file name of the module
|
||||
* @property {any} opts optional arguments
|
||||
* @property {boolean} rethrow should errors be rethrown
|
||||
*/
|
||||
/**
|
||||
* wrap a requestor handler to be compatible with express
|
||||
*
|
||||
* @param _a
|
||||
* @param {handler_description} data handler data
|
||||
* @returns {Function} requestor handler
|
||||
*/
|
||||
function get_handler (_a) {
|
||||
const { module_folder } = _a;
|
||||
const { file } = _a;
|
||||
const { opts } = _a;
|
||||
const { rethrow } = _a;
|
||||
// eslint-disable-next-line global-require
|
||||
const handler = require (path.join (process.cwd (), module_folder, file));
|
||||
return function (req, res, next) {
|
||||
return new Promise ((resolve) => resolve (handler (req, res, next, opts)))
|
||||
.catch ((e) => {
|
||||
if (rethrow)
|
||||
throw e;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* register a handler to the given app
|
||||
*
|
||||
* @param {any} app express app
|
||||
* @param {handler_description} handler_description data for the used handler
|
||||
* @param {string} method method to respond to
|
||||
* @param {string} url url to respond to
|
||||
* @param {boolean} verbose should verbose logging be enabled
|
||||
*/
|
||||
function register_handler (app, handler_description, method, url, verbose) {
|
||||
const handler = get_handler (handler_description);
|
||||
if (verbose)
|
||||
console.log (`[requestor info] redirecting ${url} to ${handler_description.file}`);
|
||||
|
||||
switch (method) {
|
||||
case 'post':
|
||||
app.post (url, handler);
|
||||
break;
|
||||
case 'get':
|
||||
app.get (url, handler);
|
||||
break;
|
||||
case 'put':
|
||||
app.put (url, handler);
|
||||
break;
|
||||
case 'delete':
|
||||
app.delete (url, handler);
|
||||
break;
|
||||
case 'all':
|
||||
app.all (url, handler);
|
||||
break;
|
||||
default:
|
||||
if (verbose)
|
||||
console.warn (`'${method}' did not match any request method, ignoring`);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all request handlers in the given folder
|
||||
*
|
||||
* @param {any} app express app
|
||||
* @param {string} module_folder folder that contains all modules
|
||||
* @param {options} options additional options
|
||||
*/
|
||||
module.exports = function main (app, module_folder, options) {
|
||||
if (options === void 0)
|
||||
options = { opts: null, subdir: '', verbose: false, rethrow: true };
|
||||
const { opts } = options;
|
||||
const { subdir } = options;
|
||||
const { verbose } = options;
|
||||
const { rethrow } = options;
|
||||
for (let _i = 0, _a = fs.readdirSync (module_folder); _i < _a.length; _i++) {
|
||||
const file = _a[_i];
|
||||
const regex = /(?<method>.*?)-(?<url>.*?)\.js/u;
|
||||
const { groups } = regex.exec (file);
|
||||
if (typeof subdir === 'undefined')
|
||||
groups.url = `/${groups.url}/`;
|
||||
else
|
||||
groups.url = `/${subdir}/${groups.url}/`;
|
||||
groups.url = groups.url
|
||||
.replace (/^\/[^/]*\/root/iu, '/')
|
||||
.replace (/\./gu, '/')
|
||||
.replace (/\/+/gu, '/');
|
||||
register_handler (app, {
|
||||
file,
|
||||
module_folder,
|
||||
opts,
|
||||
rethrow
|
||||
}, groups.method, groups.url, verbose);
|
||||
}
|
||||
};
|
39
jenkins.js
39
jenkins.js
@ -1,33 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) Sapphirecode - All Rights Reserved
|
||||
* This file is part of Requestor which is released under BSD-3-Clause.
|
||||
* See file 'LICENSE' for full license details.
|
||||
* Created by Timo Hocker <timo@scode.ovh>, March 2020
|
||||
*/
|
||||
|
||||
/* eslint-disable no-process-exit */
|
||||
/* eslint-disable no-console */
|
||||
/* eslint-disable no-sync */
|
||||
'use strict';
|
||||
|
||||
const https = require ('https');
|
||||
const fs = require ('fs');
|
||||
const child_process = require ('child_process');
|
||||
const { execSync: exec_sync } = require ('child_process');
|
||||
|
||||
const pkg = JSON.parse (fs.readFileSync ('package.json', 'utf-8'));
|
||||
[
|
||||
,, pkg.version
|
||||
const run_file = fs.createWriteStream ('.jenkins.run.js');
|
||||
|
||||
const [
|
||||
,, ...args
|
||||
] = process.argv;
|
||||
fs.writeFileSync ('package.json', JSON.stringify (pkg, null, 2));
|
||||
|
||||
child_process.execSync ('yarn lint', { stdio: 'inherit' });
|
||||
if (typeof pkg.scripts !== 'undefined' && typeof pkg.scripts.test === 'string')
|
||||
child_process.execSync ('yarn test', { stdio: 'inherit' });
|
||||
run_file.on ('close', () => {
|
||||
exec_sync (`node .jenkins.run.js ${args.join (' ')}`, { stdio: 'inherit' });
|
||||
});
|
||||
|
||||
child_process.exec ('git log -1 | grep \'\\[no publish\\]\'')
|
||||
.addListener ('exit', (code) => {
|
||||
if (code === 0) {
|
||||
console.log ('build not marked for deployment');
|
||||
process.exit (1);
|
||||
https.get (
|
||||
'https://git.scode.ovh/Timo/standard/raw/branch/master/jenkins.run.js',
|
||||
(msg) => {
|
||||
msg.pipe (run_file);
|
||||
}
|
||||
else { child_process.execSync ('yarn publish'); }
|
||||
});
|
||||
);
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Copyright (C) Sapphirecode - All Rights Reserved
|
||||
* This file is part of Requestor which is released under BSD-3-Clause.
|
||||
* See file 'LICENSE' for full license details.
|
||||
* Created by Timo Hocker <timo@scode.ovh>, March 2020
|
||||
* Created by Timo Hocker <timo@sapphirecode.ovh>, March 2020
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
@ -12,6 +12,6 @@ module.exports = {
|
||||
node: true
|
||||
},
|
||||
extends: [
|
||||
'@scode/eslint-config-ts'
|
||||
'@sapphirecode/eslint-config-ts'
|
||||
]
|
||||
}
|
||||
|
8
lib/CrudHandler.ts
Normal file
8
lib/CrudHandler.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
export interface CrudHandler {
|
||||
create(req: Request, res: Response): Promise<void>;
|
||||
read(req: Request, res: Response): Promise<void>;
|
||||
update(req: Request, res: Response): Promise<void>;
|
||||
delete(req: Request, res: Response): Promise<void>;
|
||||
}
|
160
lib/DatabaseCrudHandler.ts
Normal file
160
lib/DatabaseCrudHandler.ts
Normal file
@ -0,0 +1,160 @@
|
||||
import { Request, Response, Router } from 'express';
|
||||
import { http } from '@sapphirecode/consts';
|
||||
import { ControlModel, DatabaseModel } from '@sapphirecode/modelling';
|
||||
import { CrudHandler } from './CrudHandler';
|
||||
import { HttpHandler } from './HttpHandler';
|
||||
import { DatabaseCrudOptionsReader } from './DatabaseCrudOptionsReader';
|
||||
import { DatabaseCrudOptions } from './DatabaseCrudOptions';
|
||||
|
||||
export class DatabaseCrudHandler extends HttpHandler implements CrudHandler {
|
||||
protected cm:
|
||||
new (object: Record<string, string|number|boolean>) => ControlModel;
|
||||
|
||||
protected dm: new (id?: number) => DatabaseModel;
|
||||
protected options: DatabaseCrudOptionsReader;
|
||||
|
||||
public constructor (
|
||||
cm: new (object: Record<string, string|number|boolean>) => ControlModel,
|
||||
dm: new (id?: number) => DatabaseModel,
|
||||
options: DatabaseCrudOptions = {}
|
||||
) {
|
||||
super ();
|
||||
this.cm = cm;
|
||||
this.dm = dm;
|
||||
this.options = new DatabaseCrudOptionsReader (options);
|
||||
}
|
||||
|
||||
protected validate_body (
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<Record<string, unknown> | null> | Record<string, unknown> | null {
|
||||
if (typeof req.body === 'undefined') {
|
||||
res.status (http.status_bad_request);
|
||||
res.end ('body was undefined');
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return JSON.parse (req.body);
|
||||
}
|
||||
catch (e) {
|
||||
res.status (http.status_bad_request);
|
||||
res.end ('invalid json input');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public async create (req: Request, res: Response): Promise<void> {
|
||||
if (!await this.options.create_authorization (req, res))
|
||||
return;
|
||||
|
||||
const body_data = await this.validate_body (req, res);
|
||||
if (body_data === null)
|
||||
return;
|
||||
|
||||
const cm = new this.cm (body_data as Record<string|string, number|boolean>);
|
||||
cm.update ();
|
||||
|
||||
const dm = new this.dm;
|
||||
dm.assign (cm);
|
||||
await dm.write ();
|
||||
|
||||
res.status (http.status_created)
|
||||
.end (dm.id);
|
||||
}
|
||||
|
||||
public async read (req: Request, res: Response): Promise<void> {
|
||||
if (!await this.options.read_authorization (req, res))
|
||||
return;
|
||||
|
||||
if (typeof req.headers.id === 'undefined') {
|
||||
res.status (http.status_bad_request)
|
||||
.end ('id undefined');
|
||||
return;
|
||||
}
|
||||
|
||||
const dm = new this.dm (parseInt (req.headers.id as string));
|
||||
const found = await dm.read ();
|
||||
|
||||
const cm = new this.cm (dm.get_data ());
|
||||
cm.update ();
|
||||
|
||||
res.status (found ? http.status_ok : http.status_not_found)
|
||||
.json (cm.get_data ());
|
||||
}
|
||||
|
||||
public async update (req: Request, res: Response): Promise<void> {
|
||||
if (!await this.options.update_authorization (req, res))
|
||||
return;
|
||||
|
||||
const body_data = await this.validate_body (req, res);
|
||||
if (body_data === null)
|
||||
return;
|
||||
|
||||
if (typeof req.headers.id === 'undefined') {
|
||||
res.status (http.status_bad_request)
|
||||
.end ('id undefined');
|
||||
return;
|
||||
}
|
||||
|
||||
const dm = new this.dm (parseInt (req.headers.id as string));
|
||||
const found = await dm.read ();
|
||||
if (!found) {
|
||||
res.status (http.status_not_found)
|
||||
.end ();
|
||||
return;
|
||||
}
|
||||
|
||||
const cm = new this.cm (dm.get_data ());
|
||||
cm.update ();
|
||||
|
||||
cm.assign_object (body_data);
|
||||
cm.update ();
|
||||
|
||||
dm.assign (cm);
|
||||
|
||||
const written = await dm.write ();
|
||||
|
||||
res.status (written ? http.status_ok : http.status_internal_server_error)
|
||||
.end ();
|
||||
}
|
||||
|
||||
public async delete (req: Request, res: Response): Promise<void> {
|
||||
if (!await this.options.delete_authorization (req, res))
|
||||
return;
|
||||
|
||||
if (typeof req.headers.id === 'undefined') {
|
||||
res.status (http.status_bad_request)
|
||||
.end ('id undefined');
|
||||
return;
|
||||
}
|
||||
|
||||
const dm = new this.dm (parseInt (req.headers.id as string));
|
||||
const found = await dm.read ();
|
||||
if (!found) {
|
||||
res.status (http.status_not_found)
|
||||
.end ();
|
||||
return;
|
||||
}
|
||||
|
||||
const deleted = await dm.delete ();
|
||||
|
||||
res.status (deleted ? http.status_ok : http.status_internal_server_error)
|
||||
.end ();
|
||||
}
|
||||
|
||||
protected async create_or_update (
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<void> {
|
||||
if (typeof req.headers.id === 'undefined')
|
||||
await this.create (req, res);
|
||||
else
|
||||
await this.update (req, res);
|
||||
}
|
||||
|
||||
public register_handlers (router: Router): void {
|
||||
router.post ('/', this.create_or_update);
|
||||
router.get ('/', this.read);
|
||||
router.delete ('/', this.delete);
|
||||
}
|
||||
}
|
17
lib/DatabaseCrudOptions.ts
Normal file
17
lib/DatabaseCrudOptions.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
type Authorization = {
|
||||
(req: Request, res: Response): Promise<boolean>;
|
||||
(req: Request, res: Response, next: Function): unknown;
|
||||
}
|
||||
|
||||
interface DatabaseCrudOptions {
|
||||
general_authorization?: Authorization;
|
||||
create_authorization?: Authorization;
|
||||
read_authorization?: Authorization;
|
||||
update_authorization?: Authorization;
|
||||
delete_authorization?: Authorization;
|
||||
optional_columns?: Array<string>;
|
||||
}
|
||||
|
||||
export { Authorization, DatabaseCrudOptions };
|
74
lib/DatabaseCrudOptionsReader.ts
Normal file
74
lib/DatabaseCrudOptionsReader.ts
Normal file
@ -0,0 +1,74 @@
|
||||
import { Request, Response } from 'express';
|
||||
import { DatabaseCrudOptions, Authorization } from './DatabaseCrudOptions';
|
||||
|
||||
type AuthRunner = {
|
||||
(req: Request, res: Response): Promise<boolean>;
|
||||
}
|
||||
|
||||
export class DatabaseCrudOptionsReader {
|
||||
private _options: DatabaseCrudOptions;
|
||||
|
||||
public constructor (options: DatabaseCrudOptions) {
|
||||
this._options = options;
|
||||
}
|
||||
|
||||
private get_auth_runner (
|
||||
auth?: Authorization
|
||||
): AuthRunner {
|
||||
if (typeof auth === 'undefined')
|
||||
return (): Promise<boolean> => new Promise ((r) => r (true));
|
||||
return (req, res): Promise<boolean> => new Promise (
|
||||
(resolve: (value: boolean) => void) => {
|
||||
(async (): Promise<void> => {
|
||||
let resolved = false;
|
||||
const result = await auth (req, res, (cb: unknown) => {
|
||||
resolved = true;
|
||||
resolve (typeof cb === 'undefined' || cb === true);
|
||||
});
|
||||
if (!resolved)
|
||||
resolve (result === true);
|
||||
}) ();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public get optional_columns (): Array<string> | undefined {
|
||||
return this._options.optional_columns;
|
||||
}
|
||||
|
||||
public get create_authorization (): Authorization {
|
||||
const general = this.get_auth_runner (this._options.general_authorization);
|
||||
const specific = this.get_auth_runner (this._options.create_authorization);
|
||||
return async (req: Request, res: Response): Promise<boolean> => {
|
||||
const result = (await general (req, res)) && (await specific (req, res));
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
public get read_authorization (): Authorization {
|
||||
const general = this.get_auth_runner (this._options.general_authorization);
|
||||
const specific = this.get_auth_runner (this._options.read_authorization);
|
||||
return async (req: Request, res: Response): Promise<boolean> => {
|
||||
const result = (await general (req, res)) && (await specific (req, res));
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
public get update_authorization (): Authorization {
|
||||
const general = this.get_auth_runner (this._options.general_authorization);
|
||||
const specific = this.get_auth_runner (this._options.update_authorization);
|
||||
return async (req: Request, res: Response): Promise<boolean> => {
|
||||
const result = (await general (req, res)) && (await specific (req, res));
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
public get delete_authorization (): Authorization {
|
||||
const general = this.get_auth_runner (this._options.general_authorization);
|
||||
const specific = this.get_auth_runner (this._options.delete_authorization);
|
||||
return async (req: Request, res: Response): Promise<boolean> => {
|
||||
const result = (await general (req, res)) && (await specific (req, res));
|
||||
return result;
|
||||
};
|
||||
}
|
||||
}
|
11
lib/HttpHandler.ts
Normal file
11
lib/HttpHandler.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { Router } from 'express';
|
||||
|
||||
export abstract class HttpHandler {
|
||||
public abstract register_handlers(router: Router): void;
|
||||
|
||||
public get_router (): Router {
|
||||
const r = Router ();
|
||||
this.register_handlers (r);
|
||||
return r;
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
import { Request, Response } from '@types/express/index.d.ts';
|
||||
import Transaction from './Transaction.ts';
|
||||
|
||||
export default abstract class Handler {
|
||||
private _handlers: array<Function> = [];
|
||||
private _method_handlers: Record<string, Function> = {};
|
||||
|
||||
protected register_handler (f: Function): void {
|
||||
this._handlers.push (f);
|
||||
}
|
||||
|
||||
protected register_handler (method: string, f: Function): void {
|
||||
const m = method.toUpperCase ();
|
||||
if (typeof this._method_handlers[m] !== 'undefined')
|
||||
throw new Error (`Handler for ${m} already registered`);
|
||||
this._method_handlers[m] = f;
|
||||
}
|
||||
|
||||
private async run_method_handler (method: string, t: Transaction): void {
|
||||
const m = method.toUpperCase ();
|
||||
if (this._method_handlers[m] !== 'undefined')
|
||||
await this._method_handlers[m] (t);
|
||||
}
|
||||
|
||||
public async run_http_handler (req: Request, res: Response): void {
|
||||
const t = new Transaction (req, res);
|
||||
for (const handler of this._handlers) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
if (await handler (t) === false) {
|
||||
if (!t.status.has_status)
|
||||
t.status.error ();
|
||||
t.finalize ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
await this.run_method_handler ('ALL', t);
|
||||
await this.run_method_handler (t.req.method, t);
|
||||
}
|
||||
|
||||
public abstract get path(): string;
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
export default class Session {
|
||||
public user_id: number;
|
||||
public user_name: string;
|
||||
public permissions: Array<string>;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
import http from '@scode/consts';
|
||||
|
||||
export default class Status {
|
||||
private _status = -1;
|
||||
|
||||
public get status (): number {
|
||||
if (this._status === -1)
|
||||
throw new Error ('status undefined');
|
||||
return this._status;
|
||||
}
|
||||
|
||||
public set status (value: number): void {
|
||||
this._status = value;
|
||||
}
|
||||
|
||||
public get has_status (): boolean {
|
||||
return this._status !== -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Status setters
|
||||
*/
|
||||
|
||||
public ok (): void {
|
||||
this._status = http.status_ok;
|
||||
}
|
||||
|
||||
public ok_no_content (): void {
|
||||
this._status = http.status_ok_no_content;
|
||||
}
|
||||
|
||||
public bad_request (): void {
|
||||
this._status = http.status_bad_request;
|
||||
}
|
||||
|
||||
public unauthorized (): void {
|
||||
this._status = http.status_unauthorized;
|
||||
}
|
||||
|
||||
public forbidden (): void {
|
||||
this._status = http.status_forbidden;
|
||||
}
|
||||
|
||||
public not_found (): void {
|
||||
this._status = http.status_not_found;
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
import { Request, Response } from '@types/express/index.d.ts';
|
||||
import Status from './Status.ts';
|
||||
import Session from './Session.ts';
|
||||
|
||||
export default class Transaction {
|
||||
/* private */
|
||||
private _req: Request;
|
||||
private _res: Response;
|
||||
private _status: Status;
|
||||
|
||||
/* public */
|
||||
public get req (): Request { return this._req; }
|
||||
public get res (): Response { return this._res; }
|
||||
public get status (): Status { return this._status; }
|
||||
public session: Session;
|
||||
|
||||
/* constructor */
|
||||
public constructor (req: Request, res: Response) {
|
||||
this._req = req;
|
||||
this._res = res;
|
||||
this._status = new Status;
|
||||
}
|
||||
|
||||
/* methods */
|
||||
public finalize (): void {
|
||||
if (this._status.has_status ())
|
||||
this._res.status (this.status.status);
|
||||
this._res.end (data);
|
||||
}
|
||||
}
|
24
lib/index.ts
24
lib/index.ts
@ -1,21 +1,3 @@
|
||||
import { App } from '@types/express/index.d.ts';
|
||||
import Handler from './classes/Handler.ts';
|
||||
|
||||
/**
|
||||
* register an array of handlers to an express app
|
||||
*
|
||||
* @param {App} app express app
|
||||
* @param {Array<Handler>} handlers handlers to register
|
||||
*/
|
||||
export default function load_handlers (
|
||||
app: App,
|
||||
handlers: array<Handler>
|
||||
): void {
|
||||
for (const h of handlers)
|
||||
app.use (h.path, h.run_http_handler);
|
||||
}
|
||||
|
||||
export * from './classes/Session.ts';
|
||||
export * from './classes/Status.ts';
|
||||
export * from './classes/Transaction.ts';
|
||||
export * from './classes/Handler.ts';
|
||||
export { HttpHandler } from './HttpHandler';
|
||||
export { CrudHandler } from './CrudHandler';
|
||||
export { DatabaseCrudHandler } from './DatabaseCrudHandler';
|
||||
|
31
package.json
31
package.json
@ -1,13 +1,13 @@
|
||||
{
|
||||
"name": "@scode/requestor",
|
||||
"name": "@sapphirecode/requestor",
|
||||
"version": "1.0.0",
|
||||
"description": "Split express paths into individual files to make api programming more structured",
|
||||
"description": "Express handler templates",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"test": "nyc ava",
|
||||
"lint": "eslint .",
|
||||
"ci": "yarn --frozen-lockfile && node jenkins.js",
|
||||
"mutate": "stryker run"
|
||||
"test": "echo \"no test\"",
|
||||
"compile": "tsc",
|
||||
"lint": "eslint . --ext .js,.jsx,.ts,.tsx,.vue,.mjs",
|
||||
"ci": "yarn --frozen-lockfile && node jenkins.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -22,16 +22,19 @@
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scode/eslint-config-ts": "^1.0.12",
|
||||
"@stryker-mutator/core": "^3.1.0",
|
||||
"@stryker-mutator/javascript-mutator": "^3.1.0",
|
||||
"ava": "^3.6.0",
|
||||
"@ava/typescript": "^1.1.1",
|
||||
"@sapphirecode/eslint-config-ts": "^1.0.29",
|
||||
"eslint": "^6.8.0",
|
||||
"nyc": "^15.0.1",
|
||||
"typescript": "^3.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@scode/consts": "^1.0.15",
|
||||
"@types/express": "^4.17.4"
|
||||
}
|
||||
"@sapphirecode/consts": "^1.1.9",
|
||||
"@sapphirecode/modelling": "^1.0.19",
|
||||
"@types/express": "^4.17.6",
|
||||
"express": "^4.17.1"
|
||||
},
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"/dist/"
|
||||
]
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Sapphirecode - All Rights Reserved
|
||||
* This file is part of Requestor which is released under BSD-3-Clause.
|
||||
* See file 'LICENSE' for full license details.
|
||||
* Created by Timo Hocker <timo@scode.ovh>, March 2020
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @type {import('@stryker-mutator/api/core').StrykerOptions}
|
||||
*/
|
||||
module.exports = {
|
||||
mutator: 'javascript',
|
||||
packageManager: 'yarn',
|
||||
reporters: [
|
||||
'clear-text',
|
||||
'progress'
|
||||
],
|
||||
testRunner: 'command',
|
||||
transpilers: [],
|
||||
coverageAnalysis: 'all',
|
||||
mutate: [ 'lib/*' ]
|
||||
};
|
@ -8,7 +8,7 @@
|
||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||
// "checkJs": true, /* Report errors in .js files. */
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
// "declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||
"declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
// "sourceMap": true, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||
|
1922
yarn-error.log
Normal file
1922
yarn-error.log
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user