adding new cli helper. this cli helper is unified

This commit is contained in:
Martin Karkowski 2021-01-21 08:38:44 +01:00
parent f2b0e1ab7b
commit 9186a0655f
13 changed files with 19415 additions and 156 deletions

2
bin/nope Normal file
View File

@ -0,0 +1,2 @@
#! /usr/bin/env node
require("../dist/lib/cli/nope");

View File

@ -2,64 +2,70 @@
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2020-11-06 08:52:11
* @modify date 2020-11-06 08:52:12
* @modify date 2021-01-18 17:19:40
* @desc [description]
*/
import { ClassDeclaration, MethodDeclaration, PropertyDeclaration } from "ts-morph";
import {
ClassDeclaration,
MethodDeclaration,
PropertyDeclaration
} from "ts-morph";
import { IDecoratorFilter } from "../types/IDecoratorFilter";
export function defaultDecoratorFilter(decorators: {
class: string[],
methods: string[],
properties: string[]
}, caseSensitive = false): IDecoratorFilter{
export function defaultDecoratorFilter(
decorators: {
class: string[];
methods: string[];
properties: string[];
},
caseSensitive = false
): IDecoratorFilter {
// Update the Decorators:
if (!caseSensitive) {
decorators.class = decorators.class.map((item) => item.toLocaleLowerCase());
decorators.methods = decorators.methods.map((item) =>
item.toLocaleLowerCase()
);
decorators.properties = decorators.properties.map((item) =>
item.toLocaleLowerCase()
);
}
// Update the Decorators:
if (!caseSensitive){
decorators.class = decorators.class.map(item => item.toLocaleLowerCase());
decorators.methods = decorators.methods.map(item => item.toLocaleLowerCase());
decorators.properties = decorators.properties.map(item => item.toLocaleLowerCase());
return (declaration, decorator, mapping) => {
// Get the Name of the Decorator
let nameOfDecorator = decorator.getName();
// Let CaseSensitive or not
if (!caseSensitive) {
nameOfDecorator = nameOfDecorator.toLowerCase();
}
return (declaration, decorator, mapping) => {
// Get the Name of the Decorator
let nameOfDecorator = decorator.getName();
// Let CaseSensitive or not
if (!caseSensitive) {
nameOfDecorator = nameOfDecorator.toLowerCase();
if (declaration instanceof ClassDeclaration) {
for (const name of decorators.class) {
if (typeof mapping.aliasToOriginal[nameOfDecorator] === "string") {
if (name === mapping.aliasToOriginal[nameOfDecorator]) return true;
} else if (name === nameOfDecorator) {
return true;
}
if (declaration instanceof ClassDeclaration){
for (const name of decorators.class){
if (typeof mapping.aliasToOriginal[nameOfDecorator] === 'string') {
if (name === mapping.aliasToOriginal[nameOfDecorator])
return true;
} else if (name === nameOfDecorator){
return true;
}
}
} else if (declaration instanceof MethodDeclaration){
for (const name of decorators.methods){
if (typeof mapping.aliasToOriginal[nameOfDecorator] === 'string') {
if (name === mapping.aliasToOriginal[nameOfDecorator])
return true;
} else if (name === nameOfDecorator){
return true;
}
}
} else if (declaration instanceof PropertyDeclaration){
for (const name of decorators.properties){
if (typeof mapping.aliasToOriginal[nameOfDecorator] === 'string') {
if (name === mapping.aliasToOriginal[nameOfDecorator])
return true;
} else if (name === nameOfDecorator){
return true;
}
}
}
} else if (declaration instanceof MethodDeclaration) {
for (const name of decorators.methods) {
if (typeof mapping.aliasToOriginal[nameOfDecorator] === "string") {
if (name === mapping.aliasToOriginal[nameOfDecorator]) return true;
} else if (name === nameOfDecorator) {
return true;
}
return false
}
} else if (declaration instanceof PropertyDeclaration) {
for (const name of decorators.properties) {
if (typeof mapping.aliasToOriginal[nameOfDecorator] === "string") {
if (name === mapping.aliasToOriginal[nameOfDecorator]) return true;
} else if (name === nameOfDecorator) {
return true;
}
}
}
return false;
};
}

View File

@ -1,20 +0,0 @@
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2020-11-05 11:03:02
* @modify date 2020-11-05 11:03:04
* @desc [description]
*/
import { IFunctionDeclaredInVariableInformation } from "../types/IFunctionDeclaredInVariableInformation";
import { IFunctionFilter } from "../types/IFunctionFilter";
/**
* Method to create a Default Filter for Methods.
* @param options
*/
export function defaultFunctionFilter(options: {
functionDecorator: string,
}): IFunctionFilter {
return (func: IFunctionDeclaredInVariableInformation) => func.declarationCode.includes(options.functionDecorator + '(');
}

View File

@ -2,7 +2,7 @@
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2020-11-05 11:02:57
* @modify date 2020-11-05 11:02:59
* @modify date 2021-01-18 17:19:36
* @desc [description]
*/
@ -17,7 +17,11 @@ import { IModifierInformation } from "../types/IModifierInformation";
* Default Method for filtering Methods.
*/
export function defaultMethodFilter(): IMethodFilter {
return (cl: ClassDeclaration, method: (IMethodInformation & IDecoratorInformation & IModifierInformation), importMapping: IImportMapping) => {
return method.isPublic && method.isAsync;
}
return (
cl: ClassDeclaration,
method: IMethodInformation & IDecoratorInformation & IModifierInformation,
importMapping: IImportMapping
) => {
return method.isPublic && method.isAsync;
};
}

View File

@ -6,13 +6,13 @@
* @desc [description]
*/
import { ClassDeclaration } from "ts-morph"
import { isPropOfType } from "../helpers/isPropOfType"
import { IDecoratorInformation } from "../types/IDecoratorInformation"
import { IImportMapping } from "../types/IImportMapping"
import { IModifierInformation } from "../types/IModifierInformation"
import { IPropertyFilter } from "../types/IPropertyFilter"
import { IPropertyInformation } from "../types/IPropertyInformation"
import { ClassDeclaration } from "ts-morph";
import { isPropOfType } from "../helpers/isPropOfType";
import { IDecoratorInformation } from "../types/IDecoratorInformation";
import { IImportMapping } from "../types/IImportMapping";
import { IModifierInformation } from "../types/IModifierInformation";
import { IPropertyFilter } from "../types/IPropertyFilter";
import { IPropertyInformation } from "../types/IPropertyInformation";
/**
* Default Filter, to Filter Properties
@ -25,6 +25,6 @@ export function defaultPropertyFilter(options: {
return (cl: ClassDeclaration, property: (IPropertyInformation & IDecoratorInformation & IModifierInformation), importMapping: IImportMapping) => {
return isPropOfType(property.declaration, options.propertyType, false) &&
property.isPublic &&
property.decoratorNames.includes(options.propertyDecorator)
}
property.decoratorNames.includes(options.propertyDecorator);
};
}

View File

@ -2,7 +2,7 @@
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2020-11-11 13:27:58
* @modify date 2021-01-08 08:37:04
* @modify date 2021-01-18 18:46:10
* @desc [description]
*/
@ -12,13 +12,28 @@ import { getNopeLogger } from "../logger/getLogger";
// Define the Main Function.
// This function is used as cli tool.
const main = async function () {
export const generateDefaultConfig = async function (
additionalArguments: {
help: string;
type: "string" | "number";
name: string | string;
defaultValue?: any;
}[] = []
) {
const parser = new ArgumentParser({
version: "1.0.0",
addHelp: true,
description: "Command Line interface, determines the available Packages."
});
for (const arg of additionalArguments) {
parser.addArgument(arg.name, {
help: arg.help,
defaultValue: arg.defaultValue,
type: arg.type
});
}
parser.addArgument(["-f", "--file"], {
help: "File containing containing the package definitions.",
defaultValue: "./nopeconfig.json",
@ -62,4 +77,6 @@ const main = async function () {
}
};
main().catch((e) => console.error(e));
if (require.main === module) {
generateDefaultConfig().catch((e) => console.error(e));
}

View File

@ -2,7 +2,7 @@
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2020-11-11 13:27:58
* @modify date 2020-11-12 13:49:17
* @modify date 2021-01-18 18:48:59
* @desc [description]
*/
@ -13,66 +13,77 @@ import { getNopeLogger } from "../logger/getLogger";
// Define the Main Function.
// This function is used as cli tool.
const main = async function () {
export const generateDefaultPackageConfig = async function (
additionalArguments: {
help: string;
type: "string" | "number";
name: string | string;
defaultValue?: any;
}[] = []
) {
const parser = new ArgumentParser({
version: "1.0.0",
addHelp: true,
description: "Command Line interface, determines the available Packages."
});
const parser = new ArgumentParser({
version: "1.0.0",
addHelp: true,
description: "Command Line interface, determines the available Packages."
let opts: {
modules: string;
};
for (const arg of additionalArguments) {
parser.addArgument(arg.name, {
help: arg.help,
defaultValue: arg.defaultValue,
type: arg.type
});
}
let opts: {
modules: string,
};
try{
// Try to read in the default config file.
opts = JSON.parse(await readFile("./nopeconfig.json", {
encoding: "utf-8"
}));
} catch (error) {
opts = {} as any;
}
parser.addArgument(
["-f", "--file"],
{
help: "File containing containing the package definitions.",
defaultValue: "./config/settings.json",
type: "string",
dest: "file"
}
);
parser.addArgument(
["-s", "--search"],
{
help: "Directory containing the Modules.",
defaultValue: "not-provided",
type: "string",
dest: "modules"
}
try {
// Try to read in the default config file.
opts = JSON.parse(
await readFile("./nopeconfig.json", {
encoding: "utf-8"
})
);
} catch (error) {
opts = {} as any;
}
const args = parser.parseArgs();
parser.addArgument(["-f", "--file"], {
help: "File containing containing the package definitions.",
defaultValue: "./config/settings.json",
type: "string",
dest: "file"
});
parser.addArgument(["-s", "--search"], {
help: "Directory containing the Modules.",
defaultValue: "not-provided",
type: "string",
dest: "modules"
});
if (args.modules != "not-provided"){
opts.modules = args.modules;
}
const args = parser.parseArgs();
// Define a Logger
const logger = getNopeLogger("Setup-CLI");
if (args.modules != "not-provided") {
opts.modules = args.modules;
}
try {
logger.info("Scanning " + opts.modules);
// Write the Config.
await writeDefaultConfig(opts.modules, args.file);
// Inform the user.
logger.info("Created Package-File at " + args.file);
} catch (error) {
logger.error("Failed generating the Config");
logger.error(error);
}
// Define a Logger
const logger = getNopeLogger("Setup-CLI");
try {
logger.info("Scanning " + opts.modules);
// Write the Config.
await writeDefaultConfig(opts.modules, args.file);
// Inform the user.
logger.info("Created Package-File at " + args.file);
} catch (error) {
logger.error("Failed generating the Config");
logger.error(error);
}
};
main().catch(e => console.error(e));
if (require.main === module) {
generateDefaultPackageConfig().catch((e) => console.error(e));
}

View File

@ -0,0 +1,102 @@
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2021-01-18 17:24:49
* @modify date 2021-01-18 18:45:49
* @desc [description]
*/
import { ArgumentParser } from "argparse";
import { copyFile } from "fs/promises";
import { join } from "path";
import { createPath } from "../helpers/fileMethods";
import { getNopeLogger } from "../logger/getLogger";
const FOLDERS_TO_CREATE = [
"config",
"modules",
"open-api",
"pages",
join("public", "nope")
];
const BASE_FOLDER = __dirname;
const FILES_TO_COPY = [
// Public-Files, like logo etc.
"/public/nope/logo_light.png",
"/public/nope/logo.png",
// Default-Pages
"/pages/_app.tsx",
"/pages/index.tsx",
// Config-Files
"tsconfig.json",
"tsconfigBackend.json",
// Doc-Files:
"jsdoc.json",
// NextJS
"next.config.js",
"next-env.d.ts",
// Package File:
"package.json"
];
export async function generateFolderStructure(
additionalArguments: {
help: string;
type: "string" | "number";
name: string | string;
defaultValue?: any;
}[] = []
) {
const parser = new ArgumentParser({
version: "1.0.0",
addHelp: true,
description: "Command Line interface, determines the available Packages."
});
for (const arg of additionalArguments) {
parser.addArgument(arg.name, {
help: arg.help,
defaultValue: arg.defaultValue,
type: arg.type
});
}
parser.addArgument(["-o", "--output"], {
help: "Output Folder",
defaultValue: "./",
type: "string",
dest: "dir"
});
const args = parser.parseArgs();
for (const folder of FOLDERS_TO_CREATE) {
try {
await createPath(join(args.dir, folder));
} catch (e) {
// Define a Logger
const logger = getNopeLogger("cli");
logger.error("Failed to create directory " + folder);
logger.error(e);
}
}
for (const file of FILES_TO_COPY) {
try {
await copyFile(
join(BASE_FOLDER, "..", "..", "..", file),
join(args.dir, file)
);
} catch (e) {
// Define a Logger
const logger = getNopeLogger("cli");
logger.error("Failed to copy file " + file);
logger.error(e);
}
}
}
if (require.main === module) {
generateFolderStructure();
}

66
lib/cli/nope.ts Normal file
View File

@ -0,0 +1,66 @@
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2021-01-18 17:29:44
* @modify date 2021-01-18 18:49:54
* @desc [description]
*/
import { generateDefaultConfig } from "./generateDefaultConfig";
import { generateDefaultPackageConfig } from "./generateDefaultPackageConfig";
import { generateFolderStructure } from "./generateFolderStructure";
import { NOPELOGO } from "./renderNope";
import { readInArgs as getRunArgs, runNopeBackend } from "./runNopeBackend";
/**
* Main Function.
*
* @export
*/
export async function main() {
console.log(NOPELOGO);
console.log("\n\n");
const args: {
mode: "run" | "init" | "none" | "config";
params: string[];
} = {
mode: (process.argv[2] as any) || "none",
params: process.argv.slice(3)
};
const additionalArg: any = {
help: "Command to run the backend",
name: "cmd",
type: "string"
};
switch (args.mode) {
default:
case "none":
return;
case "run":
getRunArgs([additionalArg])
.then((args) => runNopeBackend(args).catch(console.error))
.catch(console.error);
break;
case "init":
additionalArg.help = "Command to run init";
await generateFolderStructure([additionalArg]);
await generateDefaultConfig([additionalArg]);
await generateDefaultPackageConfig([additionalArg]);
break;
case "config":
additionalArg.help = "Command to generate the Config of the backend";
await generateDefaultConfig([additionalArg]);
break;
}
}
export default main;
// If requested As Main => Perform the Operation.
if (require.main === module) {
main().catch((e) => console.error(e));
}

View File

@ -1,6 +1,13 @@
// eslint-disable-next-line quotes
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2021-01-18 18:00:39
* @modify date 2021-01-18 18:23:06
* @desc [description]
*/
export const NOPELOGO = `
----- .---. ..----******--. -------------------.
----- .---. ..----******--. -------------------.
.Peeeen. =eeeP* .oPeeeeeeeeeeeeePo|-. ....-*oeeeeeeeeeeeeeeeeePP*.........-*||-
.PeeeePo- =eeee* -eeeePn=======oPPPPPn- ....-*oeeeePPPPPPPPPPPPPPP- -**.
.PeeeeeeP* =eeee* ------ -eeeeo. *oeeeP- oeeee-

View File

@ -2,7 +2,7 @@
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2020-11-11 13:27:58
* @modify date 2021-01-08 16:26:06
* @modify date 2021-01-18 17:50:46
* @desc [description]
*/
@ -42,13 +42,28 @@ const layerDefaults = {
*
* @return {*}
*/
export async function readInArgs() {
export async function readInArgs(
additionalArguments: {
help: string;
type: "string" | "number";
name: string | string;
defaultValue?: any;
}[] = []
): Promise<any> {
const parser = new ArgumentParser({
version: "1.0.0",
addHelp: true,
description: "Command Line interface, determines the available Packages."
});
for (const arg of additionalArguments) {
parser.addArgument(arg.name, {
help: arg.help,
defaultValue: arg.defaultValue,
type: arg.type
});
}
parser.addArgument(["-f", "--file"], {
help: "File containing containing the package definitions.",
defaultValue: "./config/settings.json",

19060
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@
"description": "Nodejs Backend, combining nextjs with openapi",
"main": "index.js",
"bin": {
"nope-cli": "./bin/nope",
"runNopeBackend": "./bin/runNopeBackend",
"generateDefaultPackageConfig": "./bin/generateDefaultPackageConfig"
},