Initial content

This commit is contained in:
Adam Freeman
2024-05-29 18:54:49 +01:00
parent 2dbc1a8088
commit 5215a1d919
1944 changed files with 203378 additions and 0 deletions
@@ -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;