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,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getEnvironment = exports.Env = void 0;
var Env;
(function (Env) {
Env["Development"] = "development";
Env["Production"] = "production";
})(Env || (exports.Env = Env = {}));
const getEnvironment = () => {
const env = process.env.NODE_ENV;
return env === undefined || env === Env.Development
? Env.Development : Env.Production;
};
exports.getEnvironment = getEnvironment;
@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Env = exports.getEnvironment = exports.getConfig = void 0;
const fs_1 = require("fs");
const environment_1 = require("./environment");
Object.defineProperty(exports, "getEnvironment", { enumerable: true, get: function () { return environment_1.getEnvironment; } });
Object.defineProperty(exports, "Env", { enumerable: true, get: function () { return environment_1.Env; } });
const merge_1 = require("./merge");
const file = process.env.SERVER_CONFIG ?? "server.config.json";
const data = JSON.parse((0, fs_1.readFileSync)(file).toString());
try {
const envFile = (0, environment_1.getEnvironment)().toString() + "." + file;
const envData = JSON.parse((0, fs_1.readFileSync)(envFile).toString());
(0, merge_1.merge)(data, envData);
}
catch {
// do nothing - file doesn't exist or isn't readable
}
const getConfig = (path, defaultVal = undefined) => {
const paths = path.split(":");
let val = data;
paths.forEach(p => val = val[p]);
return val ?? defaultVal;
};
exports.getConfig = getConfig;
@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.merge = void 0;
const merge = (target, source) => {
Object.keys(source).forEach(key => {
if (typeof source[key] === "object"
&& !Array.isArray(source[key])) {
if (Object.hasOwn(target, key)) {
(0, exports.merge)(target[key], source[key]);
}
else {
Object.assign(target, source[key]);
}
}
else {
target[key] = source[key];
}
});
};
exports.merge = merge;
@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.merge = void 0;
const merge = (target, source) => {
Object.keys(source).forEach(key => {
if (typeof source[key] === "object"
&& !Array.isArray(source[key])) {
if (Object.hasOwn(target, key)) {
(0, exports.merge)(target[key], source[key]);
}
else {
Object.assign(target, source[key]);
}
}
else {
target[key] = source[key];
}
});
};
exports.merge = merge;
@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.catalog_repository = void 0;
const orm_1 = require("./orm");
exports.catalog_repository = new orm_1.CatalogRepoImpl();
@@ -0,0 +1,38 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseRepo = void 0;
const sequelize_1 = require("sequelize");
const config_1 = require("../../config");
const models_1 = require("./models");
const fs_1 = require("fs");
const config = (0, config_1.getConfig)("catalog:orm_repo");
const logging = config.logging
? { logging: console.log, logQueryParameters: true }
: { logging: false };
class BaseRepo {
sequelize;
constructor() {
this.sequelize = new sequelize_1.Sequelize({ ...config.settings, ...logging });
this.initModelsAndDatabase();
}
async initModelsAndDatabase() {
(0, models_1.initializeModels)(this.sequelize);
if (config.reset_db) {
await this.sequelize.drop();
await this.sequelize.sync();
await this.addSeedData();
}
else {
await this.sequelize.sync();
}
}
async addSeedData() {
const data = JSON.parse((0, fs_1.readFileSync)(config.seed_file).toString());
await this.sequelize.transaction(async (transaction) => {
await models_1.SupplierModel.bulkCreate(data.suppliers, { transaction });
await models_1.CategoryModel.bulkCreate(data.categories, { transaction });
await models_1.ProductModel.bulkCreate(data.products, { transaction });
});
}
}
exports.BaseRepo = BaseRepo;
@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CatalogRepoImpl = void 0;
const core_1 = require("./core");
const queries_1 = require("./queries");
const storage_1 = require("./storage");
const RepoWithQueries = (0, queries_1.AddQueries)(core_1.BaseRepo);
const CompleteRepo = (0, storage_1.AddStorage)(RepoWithQueries);
exports.CatalogRepoImpl = CompleteRepo;
@@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.initializeCatalogModels = void 0;
const sequelize_1 = require("sequelize");
const catalog_models_1 = require("./catalog_models");
const primaryKey = {
id: { type: sequelize_1.DataTypes.INTEGER, autoIncrement: true, primaryKey: true }
};
const initializeCatalogModels = (sequelize) => {
catalog_models_1.ProductModel.init({
...primaryKey,
name: { type: sequelize_1.DataTypes.STRING },
description: { type: sequelize_1.DataTypes.STRING },
price: { type: sequelize_1.DataTypes.DECIMAL(10, 2) }
}, { sequelize });
catalog_models_1.CategoryModel.init({
...primaryKey,
name: { type: sequelize_1.DataTypes.STRING }
}, { sequelize });
catalog_models_1.SupplierModel.init({
...primaryKey,
name: { type: sequelize_1.DataTypes.STRING }
}, { sequelize });
catalog_models_1.ProductModel.belongsTo(catalog_models_1.CategoryModel, { foreignKey: "categoryId", as: "category" });
catalog_models_1.ProductModel.belongsTo(catalog_models_1.SupplierModel, { foreignKey: "supplierId", as: "supplier" });
catalog_models_1.CategoryModel.hasMany(catalog_models_1.ProductModel, { foreignKey: "categoryId", as: "products" });
catalog_models_1.SupplierModel.hasMany(catalog_models_1.ProductModel, { foreignKey: "supplierId", as: "products" });
};
exports.initializeCatalogModels = initializeCatalogModels;
@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SupplierModel = exports.CategoryModel = exports.ProductModel = void 0;
const sequelize_1 = require("sequelize");
class ProductModel extends sequelize_1.Model {
}
exports.ProductModel = ProductModel;
class CategoryModel extends sequelize_1.Model {
}
exports.CategoryModel = CategoryModel;
class SupplierModel extends sequelize_1.Model {
}
exports.SupplierModel = SupplierModel;
@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.initializeModels = exports.SupplierModel = exports.CategoryModel = exports.ProductModel = void 0;
const catalog_helpers_1 = require("./catalog_helpers");
var catalog_models_1 = require("./catalog_models");
Object.defineProperty(exports, "ProductModel", { enumerable: true, get: function () { return catalog_models_1.ProductModel; } });
Object.defineProperty(exports, "CategoryModel", { enumerable: true, get: function () { return catalog_models_1.CategoryModel; } });
Object.defineProperty(exports, "SupplierModel", { enumerable: true, get: function () { return catalog_models_1.SupplierModel; } });
const initializeModels = (sequelize) => {
(0, catalog_helpers_1.initializeCatalogModels)(sequelize);
};
exports.initializeModels = initializeModels;
@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AddQueries = void 0;
const models_1 = require("./models");
function AddQueries(Base) {
return class extends Base {
getProducts() {
return models_1.ProductModel.findAll({
include: [
{ model: models_1.SupplierModel, as: "supplier" },
{ model: models_1.CategoryModel, as: "category" }
],
raw: true, nest: true
});
}
getCategories() {
return models_1.CategoryModel.findAll({
raw: true, nest: true
});
}
getSuppliers() {
return models_1.SupplierModel.findAll({
raw: true, nest: true
});
}
};
}
exports.AddQueries = AddQueries;
@@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AddStorage = void 0;
const models_1 = require("./models");
function AddStorage(Base) {
return class extends Base {
storeProduct(p) {
return this.sequelize.transaction(async (transaction) => {
if (p.category) {
p.category = await this.storeCategory(p.category);
}
if (p.supplier) {
p.supplier = await this.storeSupplier(p.supplier);
}
const [stored] = await models_1.ProductModel.upsert({
id: p.id, name: p.name, description: p.description,
price: p.price, categoryId: p.category?.id,
supplierId: p.supplier?.id
}, { transaction });
return stored;
});
}
async storeCategory(c, transaction) {
const [stored] = await models_1.CategoryModel.upsert({
id: c.id, name: c.name
}, { transaction });
return stored;
}
async storeSupplier(s, transaction) {
const [stored] = await models_1.SupplierModel.upsert({
id: s.id, name: s.name
}, { transaction });
return stored;
}
};
}
exports.AddStorage = AddStorage;
@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createErrorHandlers = void 0;
const config_1 = require("./config");
require("express-async-errors");
const template400 = (0, config_1.getConfig)("errors:400");
const template500 = (0, config_1.getConfig)("errors:500");
const createErrorHandlers = (app) => {
app.use((req, resp) => {
resp.statusCode = 404;
resp.render(template400);
});
const handler = (error, req, resp, next) => {
console.log(error);
if (resp.headersSent) {
return next(error);
}
try {
resp.statusCode = 500;
resp.render(template500, { error });
}
catch (newErr) {
next(error);
}
};
app.use(handler);
};
exports.createErrorHandlers = createErrorHandlers;
@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isDevelopment = void 0;
const config_1 = require("../config");
const isDevelopment = (value) => {
return (0, config_1.getEnvironment)() === config_1.Env.Development;
};
exports.isDevelopment = isDevelopment;
@@ -0,0 +1,39 @@
"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;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createTemplates = void 0;
const config_1 = require("../config");
const express_handlebars_1 = require("express-handlebars");
const env_helpers = __importStar(require("./env"));
const location = (0, config_1.getConfig)("templates:location");
const config = (0, config_1.getConfig)("templates:config");
const createTemplates = (app) => {
app.set("views", location);
app.engine("handlebars", (0, express_handlebars_1.engine)({
...config, helpers: { ...env_helpers }
}));
app.set("view engine", "handlebars");
};
exports.createTemplates = createTemplates;
@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createCatalogRoutes = void 0;
const data_1 = require("../data");
const createCatalogRoutes = (app) => {
app.get("/", async (req, resp) => {
const products = await data_1.catalog_repository.getProducts();
resp.render("index", { products });
});
// app.get("/err", (req, resp) => {
// throw new Error ("Something bad happened");
// });
// app.get("/asyncerr", async (req, resp) => {
// throw new Error ("Something bad happened asynchronously");
// });
};
exports.createCatalogRoutes = createCatalogRoutes;
@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createRoutes = void 0;
const catalog_1 = require("./catalog");
const createRoutes = (app) => {
(0, catalog_1.createCatalogRoutes)(app);
};
exports.createRoutes = createRoutes;
@@ -0,0 +1,23 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const http_1 = require("http");
const express_1 = __importDefault(require("express"));
const helmet_1 = __importDefault(require("helmet"));
const config_1 = require("./config");
const routes_1 = require("./routes");
const helpers_1 = require("./helpers");
const errors_1 = require("./errors");
const port = (0, config_1.getConfig)("http:port", 5000);
const expressApp = (0, express_1.default)();
expressApp.use((0, helmet_1.default)());
expressApp.use(express_1.default.json());
expressApp.use(express_1.default.urlencoded({ extended: true }));
expressApp.use(express_1.default.static("node_modules/bootstrap/dist"));
(0, helpers_1.createTemplates)(expressApp);
(0, routes_1.createRoutes)(expressApp);
(0, errors_1.createErrorHandlers)(expressApp);
const server = (0, http_1.createServer)(expressApp);
server.listen(port, () => console.log(`HTTP Server listening on port ${port}`));