Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(feat) Add support for generating modules #73

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,084 changes: 1,051 additions & 33 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"lint": "eslint .",
"lint:md": "remark .",
"lint:fix": "eslint --fix .",
"plop": "plop",
"start": "node dist/bin/server.js",
"serve": "cross-env NODE_ENV=development concurrently --kill-others-on-fail npm:serve:*",
"serve:assets": "cpx \"src/assets/**/*.*\" dist/assets --watch",
Expand Down Expand Up @@ -89,6 +90,7 @@
"js-yaml": "^4.1.0",
"mocha": "^9.2.0",
"nyc": "^15.1.0",
"plop": "^3.1.2",
"remark-cli": "^10.0.0",
"remark-lint": "^9.1.0",
"remark-preset-lint-recommended": "^6.1.1",
Expand Down
121 changes: 121 additions & 0 deletions plopfile.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
export default function (
/** @type {import('plop').NodePlopAPI} */
plop
) {
plop.setGenerator("basics", {
description: "this is a skeleton plopfile",
prompts: [
{
type: "input",
name: "name",
message: "Name your module: ",
},
{
type: "input",
name: "url",
message: " What rest base url you want for the module: ",
default: (answers) => answers.name,
},
],
actions: [
{
type: "add",
path: "src/apps/backend/modules/{{snakeCase name}}/types.ts",
templateFile: "templates/types.template.hbs",
},
{
type: "add",
path: "src/apps/backend/modules/{{snakeCase name}}/{{snakeCase name}}-service.ts",
templateFile: "templates/service.template.hbs",
},
{
type: "add",
path: "src/apps/backend/modules/{{snakeCase name}}/{{snakeCase name}}-service-manager.ts",
templateFile: "templates/service-manager.template.hbs",
},
{
type: "add",
path: "src/apps/backend/modules/{{snakeCase name}}/rest-api/{{snakeCase name}}-controller.ts",
templateFile: "templates/controller.template.hbs",
},
{
type: "add",
path: "src/apps/backend/modules/{{snakeCase name}}/rest-api/{{snakeCase name}}-rest-api-server.ts",
templateFile: "templates/rest-api-server.template.hbs",
},
{
type: "add",
path: "src/apps/backend/modules/{{snakeCase name}}/rest-api/{{snakeCase name}}-router.ts",
templateFile: "templates/router.template.hbs",
},
{
type: "add",
path: "src/apps/backend/modules/{{snakeCase name}}/internal/{{snakeCase name}}-writer.ts",
templateFile: "templates/writer.template.hbs",
},
{
type: "add",
path: "src/apps/backend/modules/{{snakeCase name}}/internal/{{snakeCase name}}-reader.ts",
templateFile: "templates/reader.template.hbs",
},
{
type: "add",
path: "src/apps/backend/modules/{{snakeCase name}}/internal/{{snakeCase name}}-utils.ts",
templateFile: "templates/utils.template.hbs",
},
{
type: "add",
path: "src/apps/backend/modules/{{snakeCase name}}/internal/store/{{snakeCase name}}-db.ts",
templateFile: "templates/db.template.hbs",
},
{
type: "add",
path: "src/apps/backend/modules/{{snakeCase name}}/internal/store/{{snakeCase name}}-repository.ts",
templateFile: "templates/repository.template.hbs",
},
{
path: 'src/apps/backend/app.ts',
pattern: /(\/\/ SERVICE MANAGER IMPORTS)/g,
template: '$1\nimport {{titleCase name}}ServiceManager from \'./modules/{{snakeCase name}}/{{snakeCase name}}-service-manager\';',
type: 'modify',
},
{
path: 'src/apps/backend/app.ts',
pattern: /(\/\/ REST API SERVER)/g,
template: `$1\n\n\t\tconst {{camleCase name}}ServiceRESTApi = await {{titleCase name}}ServiceManager.createRestAPIServer();\n\t\tapp.use('/', {{camleCase name}}ServiceRESTApi);`,
type: 'modify',
},
],
});

plop.setHelper("titleCase", (str) => {
return str.replace(/\w\S*/g, function (txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
});
});

plop.setHelper("snakeCase", (str) => {
return str
.replace(/\W+/g, " ")
.split(/ |\B(?=[A-Z])/)
.map((word) => word.toLowerCase())
.join("-");
});

plop.setHelper("titleCase", (str) => {
return str
.replace(/\W+/g, " ")
.split(/ |\B(?=[A-Z])/)
.map((txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase())
.join("");
});

plop.setHelper("camleCase", (str) => {
const string = str
.replace(/\W+/g, " ")
.split(/ |\B(?=[A-Z])/)
.map((txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase())
.join("");
return string.charAt(0).toLowerCase() + string.substr(1)
});
}
8 changes: 8 additions & 0 deletions src/apps/backend/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import cors from 'cors';
import express, { Application } from 'express';
import expressWinston from 'express-winston';

// SERVICE MANAGER IMPORTS
import AccessTokenServiceManager from './modules/access-token/access-token-manager';
import AccountServiceManager from './modules/account/account-service-manager';
import CommunicationServiceManager from './modules/communication/communication-service-manager';
import ConfigManager from './modules/config/config-manager';
import ConfigService from './modules/config/config-service';
import Logger from './modules/logger/logger';
import LoggerManager from './modules/logger/logger-manager';
import OrganizationAccountServiceManager from './modules/organization-account/organization-account-service-manager';
import TaskServiceManager from './modules/task/task-service-manager';

const isDevEnv = process.env.NODE_ENV === 'development';
Expand Down Expand Up @@ -55,6 +57,12 @@ export default class App {
}));
}

// REST API SERVER

const organizationAccountServiceRESTApi = await
OrganizationAccountServiceManager.createRestAPIServer();
app.use('/', organizationAccountServiceRESTApi);

const accountServiceRESTApi = await AccountServiceManager.createRestAPIServer();
app.use('/', accountServiceRESTApi);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export default class OrganizationAccountReader {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export default class OrganizationAccountUtil {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export default class OrganizationAccountWriter {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Schema, Types } from 'mongoose';

export interface OrganizationAccountDB {
_id: Types.ObjectId;
}

export const organizationAccountDbSchema: Schema = new Schema<OrganizationAccountDB>(
{
},
{
timestamps: {
createdAt: 'createdAt',
updatedAt: 'updatedAt',
},
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import mongoose, { CallbackError, Connection } from 'mongoose';

import ConfigService from '../../../config/config-service';

import { OrganizationAccountDB, organizationAccountDbSchema } from './organization-account-db';

export default class OrganizationAccountRepository {
public static organizationAccountDB: mongoose.Model<OrganizationAccountDB>;

static async createDBConnection(): Promise<Connection> {
return new Promise((resolve, reject) => {
const mongoURI = ConfigService.getStringValue('mongoDb.uri');
mongoose.createConnection(
mongoURI,
{},
(error: CallbackError, result: Connection): void => {
if (error) {
reject(error);
} else {
OrganizationAccountRepository.organizationAccountDB = result.model(
'OrganizationAccount',
organizationAccountDbSchema,
) as unknown as mongoose.Model<OrganizationAccountDB>;
resolve(result);
}
},
);
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Application } from 'express';

import OrganizationAccountRESTApiServer from './rest-api/organization-account-rest-api-server';

export default class OrganizationAccountServiceManager {
public static async createRestAPIServer(): Promise<Application> {
return OrganizationAccountRESTApiServer.create();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export default class OrganizationAccountService {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {
NextFunction, Request, Response,
} from 'express';

export default class OrganizationAccountController {
public static createOrganizationAccount(
_req: Request,
res: Response,
next: NextFunction,
): void {
try {
res.status(201).send({});
} catch (e) {
next(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import bodyParser from 'body-parser';
import express, { Application } from 'express';

import ErrorHandler from '../../error/error-handler';
import OrganizationAccountRepository from '../internal/store/organization-account-repository';

import OrganizationAccountRouter from './organization-account-router';

export default class OrganizationAccountRESTApiServer {
public static async create(): Promise<Application> {
await OrganizationAccountRepository.createDBConnection();

const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

app.use('/organization-account', OrganizationAccountRouter.getRoutes());

app.use(ErrorHandler.AppErrorHandler);

return Promise.resolve(app);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* eslint-disable @typescript-eslint/no-misused-promises */
import { Router } from 'express';

import OrganizationAccountController from './organization-account-controller';

export default class OrganizationAccountRouter {
public static getRoutes(): Router {
const router = Router();

router.post('/', OrganizationAccountController.createOrganizationAccount);

return router;
}
}
3 changes: 3 additions & 0 deletions src/apps/backend/modules/organization-account/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default class OrganizationAccount {
id: string;
}
17 changes: 17 additions & 0 deletions templates/controller.template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {
NextFunction, Request, Response,
} from 'express';

export default class {{titleCase name}}Controller {
public static create{{titleCase name}}(
_req: Request,
res: Response,
next: NextFunction,
): void {
try {
res.status(201).send({});
} catch (e) {
next(e);
}
}
}
16 changes: 16 additions & 0 deletions templates/db.template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Schema, Types } from 'mongoose';

export interface {{titleCase name}}DB {
_id: Types.ObjectId;
}

export const {{camleCase name}}DbSchema: Schema = new Schema<{{titleCase name}}DB>(
{
},
{
timestamps: {
createdAt: 'createdAt',
updatedAt: 'updatedAt',
},
},
);
2 changes: 2 additions & 0 deletions templates/reader.template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export default class {{titleCase name}}Reader {
}
30 changes: 30 additions & 0 deletions templates/repository.template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import mongoose, { CallbackError, Connection } from 'mongoose';

import ConfigService from '../../../config/config-service';

import { {{titleCase name}}DB, {{camleCase name}}DbSchema } from './{{snakeCase name}}-db';

export default class {{titleCase name}}Repository {
public static {{camleCase name}}DB: mongoose.Model<{{titleCase name}}DB>;

static async createDBConnection(): Promise<Connection> {
return new Promise((resolve, reject) => {
const mongoURI = ConfigService.getStringValue('mongoDb.uri');
mongoose.createConnection(
mongoURI,
{},
(error: CallbackError, result: Connection): void => {
if (error) {
reject(error);
} else {
{{titleCase name}}Repository.{{camleCase name}}DB = result.model(
'{{titleCase name}}',
{{camleCase name}}DbSchema,
) as unknown as mongoose.Model<{{titleCase name}}DB>;
resolve(result);
}
},
);
});
}
}
23 changes: 23 additions & 0 deletions templates/rest-api-server.template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import bodyParser from 'body-parser';
import express, { Application } from 'express';

import ErrorHandler from '../../error/error-handler';
import {{titleCase name}}Repository from '../internal/store/{{snakeCase name}}-repository';

import {{titleCase name}}Router from './{{snakeCase name}}-router';

export default class {{titleCase name}}RESTApiServer {
public static async create(): Promise<Application> {
await {{titleCase name}}Repository.createDBConnection();

const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

app.use('/{{snakeCase url}}', {{titleCase name}}Router.getRoutes());

app.use(ErrorHandler.AppErrorHandler);

return Promise.resolve(app);
}
}
Loading
Loading