Initial content
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.FeathersWrapper = void 0;
|
||||
class FeathersWrapper {
|
||||
ws;
|
||||
constructor(ws) {
|
||||
this.ws = ws;
|
||||
}
|
||||
get(id) {
|
||||
return this.ws.getOne(id);
|
||||
}
|
||||
find(params) {
|
||||
return this.ws.getMany(params.query);
|
||||
}
|
||||
create(data, params) {
|
||||
return this.ws.store(data);
|
||||
}
|
||||
remove(id, params) {
|
||||
return this.ws.delete(id);
|
||||
}
|
||||
update(id, data, params) {
|
||||
return this.ws.replace(id, data);
|
||||
}
|
||||
patch(id, data, params) {
|
||||
return this.ws.modify(id, data);
|
||||
}
|
||||
}
|
||||
exports.FeathersWrapper = FeathersWrapper;
|
||||
@@ -0,0 +1,73 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createAdapter = void 0;
|
||||
const validation_types_1 = require("./validation_types");
|
||||
function createAdapter(app, ws, baseUrl) {
|
||||
app.get(baseUrl, async (req, resp) => {
|
||||
try {
|
||||
resp.json(await ws.getMany(req.query));
|
||||
resp.end();
|
||||
}
|
||||
catch (err) {
|
||||
writeErrorResponse(err, resp);
|
||||
}
|
||||
});
|
||||
app.get(`${baseUrl}/:id`, async (req, resp) => {
|
||||
try {
|
||||
const data = await ws.getOne((req.params.id));
|
||||
if (data == undefined) {
|
||||
resp.writeHead(404);
|
||||
}
|
||||
else {
|
||||
resp.json(data);
|
||||
}
|
||||
resp.end();
|
||||
}
|
||||
catch (err) {
|
||||
writeErrorResponse(err, resp);
|
||||
}
|
||||
});
|
||||
app.post(baseUrl, async (req, resp) => {
|
||||
try {
|
||||
const data = await ws.store(req.body);
|
||||
resp.json(data);
|
||||
resp.end();
|
||||
}
|
||||
catch (err) {
|
||||
writeErrorResponse(err, resp);
|
||||
}
|
||||
});
|
||||
app.delete(`${baseUrl}/:id`, async (req, resp) => {
|
||||
try {
|
||||
resp.json(await ws.delete(req.params.id));
|
||||
resp.end();
|
||||
}
|
||||
catch (err) {
|
||||
writeErrorResponse(err, resp);
|
||||
}
|
||||
});
|
||||
app.put(`${baseUrl}/:id`, async (req, resp) => {
|
||||
try {
|
||||
resp.json(await ws.replace(req.params.id, req.body));
|
||||
resp.end();
|
||||
}
|
||||
catch (err) {
|
||||
writeErrorResponse(err, resp);
|
||||
}
|
||||
});
|
||||
app.patch(`${baseUrl}/:id`, async (req, resp) => {
|
||||
try {
|
||||
resp.json(await ws.modify(req.params.id, req.body));
|
||||
resp.end();
|
||||
}
|
||||
catch (err) {
|
||||
writeErrorResponse(err, resp);
|
||||
}
|
||||
});
|
||||
const writeErrorResponse = (err, resp) => {
|
||||
console.error(err);
|
||||
resp.writeHead(err instanceof validation_types_1.ValidationError ? 400 : 500);
|
||||
resp.end();
|
||||
};
|
||||
}
|
||||
exports.createAdapter = createAdapter;
|
||||
@@ -0,0 +1,65 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createApi = void 0;
|
||||
const results_api_1 = require("./results_api");
|
||||
const validation_adapter_1 = require("./validation_adapter");
|
||||
const results_api_validation_1 = require("./results_api_validation");
|
||||
const feathers_adapter_1 = require("./feathers_adapter");
|
||||
const feathers_1 = require("@feathersjs/feathers");
|
||||
const express_1 = __importStar(require("@feathersjs/express"));
|
||||
const validation_types_1 = require("./validation_types");
|
||||
const auth_1 = require("../auth");
|
||||
const passport_1 = __importDefault(require("passport"));
|
||||
const createApi = (app) => {
|
||||
const feathersApp = (0, express_1.default)((0, feathers_1.feathers)(), app).configure((0, express_1.rest)());
|
||||
const service = new validation_adapter_1.Validator(new results_api_1.ResultWebService(), results_api_validation_1.ResultWebServiceValidation);
|
||||
feathersApp.use('/api/results', passport_1.default.authenticate("jwt", { session: false }), (req, resp, next) => {
|
||||
req.feathers.user = req.user;
|
||||
req.feathers.authenticated
|
||||
= req.authenticated = req.user !== undefined;
|
||||
next();
|
||||
}, new feathers_adapter_1.FeathersWrapper(service));
|
||||
feathersApp.hooks({
|
||||
error: {
|
||||
all: [(ctx) => {
|
||||
if (ctx.error instanceof validation_types_1.ValidationError) {
|
||||
ctx.http = { status: 400 };
|
||||
ctx.error = undefined;
|
||||
}
|
||||
}]
|
||||
},
|
||||
before: {
|
||||
create: [(0, auth_1.roleHook)("Users")],
|
||||
remove: [(0, auth_1.roleHook)("Admins")],
|
||||
update: [(0, auth_1.roleHook)("Admins")],
|
||||
patch: [(0, auth_1.roleHook)("Admins")]
|
||||
}
|
||||
});
|
||||
};
|
||||
exports.createApi = createApi;
|
||||
@@ -0,0 +1,68 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ResultWebService = void 0;
|
||||
const data_1 = __importDefault(require("../data"));
|
||||
const jsonpatch = __importStar(require("fast-json-patch"));
|
||||
const validation_functions_1 = require("./validation_functions");
|
||||
const results_api_validation_1 = require("./results_api_validation");
|
||||
class ResultWebService {
|
||||
getOne(id) {
|
||||
return data_1.default.getResultById(id);
|
||||
}
|
||||
getMany(query) {
|
||||
if (query.name) {
|
||||
return data_1.default.getResultsByName(query.name, 10);
|
||||
}
|
||||
else {
|
||||
return data_1.default.getAllResults(10);
|
||||
}
|
||||
}
|
||||
async store(data) {
|
||||
const { name, age, years } = data;
|
||||
const nextage = age + years;
|
||||
const id = await data_1.default.saveResult({ id: 0, name, age,
|
||||
years, nextage });
|
||||
return await data_1.default.getResultById(id);
|
||||
}
|
||||
delete(id) {
|
||||
return data_1.default.delete(Number.parseInt(id));
|
||||
}
|
||||
replace(id, data) {
|
||||
const { name, age, years, nextage } = data;
|
||||
const validated = (0, validation_functions_1.validateModel)({ name, age, years, nextage }, results_api_validation_1.ResultModelValidation);
|
||||
return data_1.default.update({ id, ...validated });
|
||||
}
|
||||
async modify(id, data) {
|
||||
const dbData = await this.getOne(id);
|
||||
if (dbData !== undefined) {
|
||||
return await this.replace(id, jsonpatch.applyPatch(dbData, data).newDocument);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.ResultWebService = ResultWebService;
|
||||
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ResultModelValidation = exports.ResultWebServiceValidation = void 0;
|
||||
const validator_1 = __importDefault(require("validator"));
|
||||
const intValidator = {
|
||||
validation: [val => validator_1.default.isInt(val.toString())],
|
||||
converter: (val) => Number.parseInt(val)
|
||||
};
|
||||
const partialResultValidator = {
|
||||
name: [(val) => !validator_1.default.isEmpty(val)],
|
||||
age: intValidator,
|
||||
years: intValidator
|
||||
};
|
||||
exports.ResultWebServiceValidation = {
|
||||
keyValidator: intValidator,
|
||||
store: partialResultValidator,
|
||||
replace: {
|
||||
...partialResultValidator,
|
||||
nextage: intValidator
|
||||
}
|
||||
};
|
||||
exports.ResultModelValidation = {
|
||||
propertyRules: { ...partialResultValidator, nextage: intValidator },
|
||||
modelRule: [(m) => m.nextage === m.age + m.years]
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Validator = void 0;
|
||||
const validation_functions_1 = require("./validation_functions");
|
||||
class Validator {
|
||||
ws;
|
||||
validation;
|
||||
constructor(ws, validation) {
|
||||
this.ws = ws;
|
||||
this.validation = validation;
|
||||
}
|
||||
getOne(id) {
|
||||
return this.ws.getOne(this.validateId(id));
|
||||
}
|
||||
getMany(query) {
|
||||
if (this.validation.getMany) {
|
||||
query = (0, validation_functions_1.validate)(query, this.validation.getMany);
|
||||
}
|
||||
return this.ws.getMany(query);
|
||||
}
|
||||
store(data) {
|
||||
if (this.validation.store) {
|
||||
data = (0, validation_functions_1.validate)(data, this.validation.store);
|
||||
}
|
||||
return this.ws.store(data);
|
||||
}
|
||||
delete(id) {
|
||||
return this.ws.delete(this.validateId(id));
|
||||
}
|
||||
replace(id, data) {
|
||||
if (this.validation.replace) {
|
||||
data = (0, validation_functions_1.validate)(data, this.validation.replace);
|
||||
}
|
||||
return this.ws.replace(this.validateId(id), data);
|
||||
}
|
||||
modify(id, data) {
|
||||
if (this.validation.modify) {
|
||||
data = (0, validation_functions_1.validate)(data, this.validation.modify);
|
||||
}
|
||||
return this.ws.modify(this.validateId(id), data);
|
||||
}
|
||||
validateId(val) {
|
||||
return (0, validation_functions_1.validateIdProperty)(val, this.validation);
|
||||
}
|
||||
}
|
||||
exports.Validator = Validator;
|
||||
@@ -0,0 +1,57 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.validateModel = exports.validateIdProperty = exports.validate = void 0;
|
||||
const validation_types_1 = require("./validation_types");
|
||||
function validate(data, reqs) {
|
||||
let validatedData = {};
|
||||
Object.entries(reqs).forEach(([prop, rule]) => {
|
||||
const [valid, value] = applyRule(data[prop], rule);
|
||||
if (valid) {
|
||||
validatedData[prop] = value;
|
||||
}
|
||||
else {
|
||||
throw new validation_types_1.ValidationError(prop, "Validation Error");
|
||||
}
|
||||
});
|
||||
return validatedData;
|
||||
}
|
||||
exports.validate = validate;
|
||||
function applyRule(val, rule) {
|
||||
const required = Array.isArray(rule) ? true : rule.required;
|
||||
const checks = Array.isArray(rule) ? rule : rule.validation;
|
||||
const convert = Array.isArray(rule) ? (v) => v : rule.converter;
|
||||
if (val === null || val == undefined || val === "") {
|
||||
return [required ? false : true, val];
|
||||
}
|
||||
let valid = true;
|
||||
checks.forEach(check => {
|
||||
if (!check(val)) {
|
||||
valid = false;
|
||||
}
|
||||
});
|
||||
return [valid, convert ? convert(val) : val];
|
||||
}
|
||||
function validateIdProperty(val, v) {
|
||||
if (v.keyValidator) {
|
||||
const [valid, value] = applyRule(val, v.keyValidator);
|
||||
if (valid) {
|
||||
return value;
|
||||
}
|
||||
throw new validation_types_1.ValidationError("ID", "Validation Error");
|
||||
}
|
||||
return val;
|
||||
}
|
||||
exports.validateIdProperty = validateIdProperty;
|
||||
function validateModel(model, rules) {
|
||||
if (rules.propertyRules) {
|
||||
model = validate(model, rules.propertyRules);
|
||||
}
|
||||
if (rules.modelRule) {
|
||||
const [valid, data] = applyRule(model, rules.modelRule);
|
||||
if (valid) {
|
||||
return data;
|
||||
}
|
||||
throw new validation_types_1.ValidationError("Model", "Validation Error");
|
||||
}
|
||||
}
|
||||
exports.validateModel = validateModel;
|
||||
@@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ValidationError = void 0;
|
||||
class ValidationError {
|
||||
name;
|
||||
message;
|
||||
constructor(name, message) {
|
||||
this.name = name;
|
||||
this.message = message;
|
||||
}
|
||||
stack;
|
||||
cause;
|
||||
}
|
||||
exports.ValidationError = ValidationError;
|
||||
Reference in New Issue
Block a user