Compare commits

29 Commits

Author SHA1 Message Date
cbf56b54c1 Fix: info log return in Log module 2024-05-02 02:08:08 +02:00
1f121a8565 Added: error log in Log module 2024-05-02 00:10:39 +02:00
ae5ceb643f Added environment module 2024-04-04 01:32:29 +02:00
2e2352aa57 Starting rewriting nork from scratch 2024-04-02 22:08:41 +02:00
6a1a6f6e68 Added example compose files for databases 2024-04-02 21:13:00 +02:00
4f52c37cb3 Drop support for javascript 2024-03-30 15:46:18 +01:00
03fbb74171 code formatted 2022-07-30 22:44:24 +02:00
564cd09d8b Merge pull request #8 from filiprojek/updates
changes:  - norkconfig se generuje lepe a actually ho pouzivam  - pri vytvareni projektu je mozne vybrat si orm (mongoose & sequlize)  - default modely pro db se kopiruji na zaklade parametru db z norkconfigu  - updatnutej ts skeleton  - dropnul jsem support pro js
2022-07-30 22:30:10 +02:00
d8b859850e changes:
- norkconfig se generuje lepe a actually ho pouzivam
 - pri vytvareni projektu je mozne vybrat si orm (mongoose & sequlize)
 - default modely pro db se kopiruji na zaklade parametru db z norkconfigu
 - updatnutej ts skeleton
 - dropnul jsem support pro js
2022-07-30 22:28:06 +02:00
3b85bad8a7 Merge pull request #6 from filiprojek/githooks
feat: githooks
2022-02-02 16:21:23 +01:00
f71e76be5d feat: githooks 2022-02-02 16:20:24 +01:00
8afcd04a09 feat: githooks 2022-02-02 16:19:03 +01:00
95e60bc04e nork 3.0.4 2022-02-02 16:01:34 +01:00
100eb59f17 nork works 2022-02-01 19:11:54 +01:00
9c03dbef15 nork works 2022-02-01 19:11:48 +01:00
00033fd439 npm fixes 2022-01-13 11:43:47 +01:00
c988ef64c4 Rewrited to TypeScript, better file structure 2022-01-12 23:15:24 +01:00
5eafee03b2 Remove ignored files 2021-12-01 18:12:11 +01:00
f887fc026a cleaning 2021-12-01 18:08:52 +01:00
2f437f9696 gitignore updated 2021-12-01 18:06:43 +01:00
1ebafbef49 rewriting to oop and typescript 2021-12-01 18:05:44 +01:00
67d6029699 version updated 2021-11-09 15:16:12 +01:00
49e34b5f73 bug fix 2021-11-09 15:15:54 +01:00
36758cbadb To be honest, I do not quite remember everything I changed here today. But it is all good, I tell ya. 2021-11-03 17:35:24 +01:00
686cddefed readme & version updated 2021-08-19 16:17:48 +02:00
e2f4243516 Update README.md 2021-08-19 16:17:18 +02:00
4de0bce7a1 create project in current directory
package.json updated
2021-08-19 16:14:44 +02:00
ff902c85ac readme 2021-08-19 11:16:17 +02:00
3092aea183 Readme and help updated 2021-08-18 11:46:54 +02:00
65 changed files with 387 additions and 1154 deletions

25
.eslintrc.json Normal file
View File

@@ -0,0 +1,25 @@
{
"env": {
"es2021": true,
"node": true
},
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"rules": {
"indent": ["error", "tab"],
"linebreak-style": ["error", "unix"],
"quotes": [
"error",
"single",
{
"allowTemplateLiterals": true
}
],
"semi": ["error", "never"]
}
}

59
.githooks/pre-push Executable file
View File

@@ -0,0 +1,59 @@
#!/bin/bash
# @link https://gist.github.com/mattscilipoti/8424018
#
# Called by "git push" after it has checked the remote status,
# but before anything has been pushed.
#
# If this script exits with a non-zero status nothing will be pushed.
#
# Steps to install, from the root directory of your repo...
# 1. Copy the file into your repo at `.git/hooks/pre-push`
# 2. Set executable permissions, run `chmod +x .git/hooks/pre-push`
# 3. Or, use `rake hooks:pre_push` to install
#
# Try a push to master, you should get a message `*** [Policy] Never push code directly to...`
#
# The commands below will not be allowed...
# `git push origin master`
# `git push --force origin master`
# `git push --delete origin master`
protected_branch='master'
policy="\n\n[Policy] Never push code directly to the "$protected_branch" branch! (Prevented with pre-push hook.)\n\n"
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
push_command=$(ps -ocommand= -p $PPID)
is_destructive='force|delete|\-f'
will_remove_protected_branch=':'$protected_branch
do_exit(){
echo -e $policy
exit 1
}
if [[ $push_command =~ $is_destructive ]] && [ $current_branch = $protected_branch ]; then
do_exit
fi
if [[ $push_command =~ $is_destructive ]] && [[ $push_command =~ $protected_branch ]]; then
do_exit
fi
if [[ $push_command =~ $will_remove_protected_branch ]]; then
do_exit
fi
# Prevent ALL pushes to protected_branch
if [[ $push_command =~ $protected_branch ]] || [ $current_branch = $protected_branch ]; then
do_exit
fi
unset do_exit
exit 0

6
.gitignore vendored
View File

@@ -104,4 +104,8 @@ dist
.tern-port .tern-port
# package lock file # package lock file
package-lock.json package-lock.json
_old/
undefined.ts
undefined.ejs

4
.mocharc.json Normal file
View File

@@ -0,0 +1,4 @@
{
"require": ["ts-node/register"],
"watch-files": ["./src/**/*.ts"]
}

15
.prettierrc Normal file
View File

@@ -0,0 +1,15 @@
{
"tabWidth": 4,
"useTabs": true,
"singleQuote": true,
"semi": false,
"trailingComma": "none",
"jsxSingleQuote": true,
"jsxBracketSameLine": true,
"printWidth": 200,
"bracketSpacing": true,
"vueIndentScriptAndStyle": true,
"arrowParens": "always",
"bracketSameLine": false,
"endOfLine": "lf"
}

View File

@@ -1,22 +1,29 @@
# Nork # Nork
Simple node.js tool that extends express projects. Simple node.js tool that extends express projects.
- [About](#about) - [About](#about)
- [Installation](#installation) - [Installation](#installation)
- [How to use](#how-to-use) - [How to use](#how-to-use)
## About ## About
The point of this tool is to add to express some feeling of php framework Laravel. Primarily get simply express app into MVC architecture. The point of this tool is to add to express some feeling of php framework Laravel. Primarily get simply express app into MVC architecture.
## Installation ## Installation
``` ```
npm install -g nork npm install -g nork
``` ```
This will install nork globally. If you would like to install nork for only one project, you can also install it locally. For local installation: This will install nork globally. If you would like to install nork for only one project, you can also install it locally. For local installation:
```
npm install nork
``` ```
npm install nork
```
## How to use ## How to use
``` ```
Usage: nork <command> [options] Usage: nork <command> [options]
@@ -26,11 +33,12 @@ Options:
Commands: Commands:
create [app-name] create a new project create [app-name] create a new project
make:controller create a new controller create [app-name] -i create a new project in current directory
make:middleware create a new middleware make controller [name] create a new controller
make:model create a new model make middleware [name] create a new middleware
make:route create a new route make model [name] create a new model
make:test create a new test make route [name] create a new route
make:view create a new view make test [name] create a new test
make view [name] create a new view
setup set up an existing project for nork setup set up an existing project for nork
``` ```

1
norkconfig.json Normal file
View File

@@ -0,0 +1 @@
{ "lang": "ts" }

View File

@@ -1,32 +1,61 @@
{ {
"name": "nork", "name": "nork",
"version": "1.1.3", "version": "3.0.5",
"description": "The best node.js 'framework' :)", "description": "The best node.js 'framework' :)",
"main": "src/app.js", "main": "dist/app.js",
"bin": "src/app.js", "bin": "dist/app.js",
"scripts": { "types": "dist/app.d.ts",
"start": "node src/app.js" "scripts": {
}, "start": "npm run start:prod",
"keywords": [ "start:dev": "ts-node src/app.ts",
"node", "start:prod": "node dist/app.js",
"framework", "tsc": "tsc -p .",
"express", "clean": "rimraf dist",
"mvc" "copy-assets": "ts-node src/utils/copyAssets",
], "build": "npm-run-all clean tsc copy-assets",
"author": "Filip Rojek", "test": "mocha --config .mocharc.json --watch src/**/*.test.ts",
"license": "MIT", "prepublish": "npm-run-all build",
"dependencies": { "format": "npx prettier --write ."
"colors": "^1.4.0", },
"fs-extra": "^10.0.0", "keywords": [
"inquirer": "^8.1.2", "node",
"pad": "^3.2.0" "framework",
}, "express",
"repository": { "mvc"
"type": "git", ],
"url": "git+https://github.com/filiprojek/nork.git" "author": "Filip Rojek",
}, "license": "MIT",
"bugs": { "dependencies": {
"url": "https://github.com/filiprojek/nork/issues" "colors": "1.4.0",
}, "dotenv": "^16.4.5",
"homepage": "https://github.com/filiprojek/nork/blob/master/README.md" "fs-extra": "^10.0.0",
"inquirer": "^8.1.2",
"pad": "^3.2.0"
},
"devDependencies": {
"@types/chai": "^4.2.22",
"@types/fs-extra": "^9.0.13",
"@types/inquirer": "^8.1.3",
"@types/mocha": "^9.0.0",
"@types/shelljs": "^0.8.11",
"@typescript-eslint/eslint-plugin": "^5.5.0",
"@typescript-eslint/parser": "^5.5.0",
"chai": "^4.3.4",
"eslint": "^8.3.0",
"mocha": "^9.1.3",
"npm-run-all": "^4.1.5",
"prettier": "^2.7.1",
"rimraf": "^3.0.2",
"shelljs": "^0.8.5",
"ts-node": "^10.4.0",
"typescript": "^4.5.2"
},
"repository": {
"type": "git",
"url": "git+https://github.com/filiprojek/nork.git"
},
"bugs": {
"url": "https://github.com/filiprojek/nork/issues"
},
"homepage": "https://github.com/filiprojek/nork/blob/master/README.md"
} }

49
progress-blog.md Normal file
View File

@@ -0,0 +1,49 @@
/_ spell-checker: disable _/
# Todo:
- [ ] auth jwt refresh token based system
- https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/
- [ ] version of nork control
- [ ] upgrade to newer version system
- [ ] updatnout make files (obzvlast modely a rozlisovat modely podle norkconfigu)
- [ ] vyzadovat aktualni verzi 3.#.# pro make commandy (pouzivaly se jiny predtim soubory)
- [ ] moznost vytvorit projekt bez db
### 11-24-2021
- zacal jsem predelavat nork do OOP
- co jsem udelal:
- [x] --help
- [x] --version
- [x] setup
- [x] make
- [x] create
- delam na tom
- je treba dopsat par types a fixnout zbytek erroru
- zatim netestovana funkcnost
### 1-10-2022
- dodelal jsem create a otestoval ho
- [x] create
### 7-30-2022
- norkconfig se generuje lepe a actually ho pouzivam
- pri vytvareni projektu je mozne vybrat si orm (mongoose & sequlize)
- default modely pro db se kopiruji na zaklade parametru db z norkconfigu
- updatnutej ts skeleton
- dropnul jsem support pro js
- version update: 3.0.5
### 4-03-2024
- [ ] modules
- [ ] Log
- [ ] Auth
- [ ] Env
- [ ] Docs
- [ ] Databases
- [ ] CLI

5
setup-repo.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash
cp .githooks/* .git/hooks
echo "hooks have been copied"

View File

@@ -1,221 +0,0 @@
#!/usr/bin/env node
const inquirer = require('inquirer')
const path = require('path')
const fs = require('fs-extra')
const colors = require('colors')
const pad = require('pad')
const langToLanguage = lang => {
switch (lang) {
case 'js':
return 'Javascript'
case 'ts':
return 'Typescript'
default:
return 'Unknown language'
}
}
const logError = errorMsg => {
console.log(colors.bgYellow.red(errorMsg))
return
}
const logSuccess = (msg = false) => {
if (!msg) {
msg = 'Success!'
}
console.log(colors.cyan(msg))
return
}
const logHelp = (specific = false, command = false) => {
let spc = 40
if (specific) {
// log specific help
if (specific == 'make') {
console.log(`Usage: ${specific}:[component]`)
console.log()
console.log(pad(' make:controller', spc), 'create a new controller')
console.log(pad(' make:middleware', spc), 'create a new middleware')
console.log(pad(' make:model', spc), 'create a new model')
console.log(pad(' make:route', spc), 'create a new route')
console.log(pad(' make:test', spc), 'create a new test')
console.log(pad(' make:view', spc), 'create a new view')
return
}
console.log(`Usage: ${specific} [options]`)
return
}
console.log('Usage: nork <command> [options]')
console.log()
console.log('Options:')
console.log(pad(' -v, --version', spc), 'output the version number')
console.log(pad(' -h, --help', spc), 'output usage information')
console.log()
console.log('Commands:')
console.log(pad(' create [app-name]', spc), 'create a new project')
console.log(pad(' make:controller', spc), 'create a new controller')
console.log(pad(' make:middleware', spc), 'create a new middleware')
console.log(pad(' make:model', spc), 'create a new model')
console.log(pad(' make:route', spc), 'create a new route')
console.log(pad(' make:test', spc), 'create a new test')
console.log(pad(' make:view', spc), 'create a new view')
console.log(pad(' setup', spc), 'set up an existing project for nork')
console.log()
console.log(' Run', colors.cyan('nork help <command>'), 'for detailed usage of given command.')
if (command) {
console.log(colors.red('Unknown command'), colors.bold.blue(command))
}
return
}
;(async () => {
if (process.argv[2] == 'create') {
// get info about new project
const data = {}
const questions = [
{
type: 'input',
name: 'project_name',
message: 'Enter project name:',
},
{
type: 'list',
message: "Pick the technology you're using:",
name: 'lang',
choices: [
{ name: 'Typescript', value: 'ts' },
{ name: 'Javascript', value: 'js' },
],
},
{
type: 'input',
name: 'author',
message: 'Enter your name:',
},
]
// remove first question if project name is already known
if (process.argv[3]) {
questions.shift()
}
let answers = await inquirer.prompt(questions)
data.project_name = answers.project_name ? answers.project_name : process.argv[3]
data.lang = answers.lang
data.author = answers.author
// copy skeleton to new project
fs.copySync(path.join(__dirname, './skeletons/express-' + data.lang), process.cwd())
// edit package.json file
const pkgJson = require(path.join(process.cwd(), 'package.json'))
pkgJson.name = data.project_name
pkgJson.author = data.author
fs.writeFile(path.join(process.cwd(), 'package.json'), JSON.stringify(pkgJson, null, 2), err => {
if (err) return logError(err)
})
console.log(colors.yellow('Project settings'))
console.log(colors.yellow('------------------'))
console.log(pad(colors.gray('Project name: '), 30), data.project_name)
console.log(pad(colors.gray('Author: '), 30), data.author)
console.log(pad(colors.gray('Language: '), 30), langToLanguage(data.lang))
return logSuccess(`Project ${data.project_name} created successfully!`)
}
if (process.argv[2] == 'make') {
if (!process.argv[3] || !process.argv[4]) return logHelp('make')
const component = process.argv[3]
const norkcfg = require(path.join(process.cwd(), 'norkconfig.json'))
let tsComponents = ['controller', 'middleware', 'route']
if (tsComponents.includes(component)) {
let src = path.join(__dirname, './make-files/express-' + norkcfg.lang + '/' + component + '.' + norkcfg.lang)
let dest = path.join(process.cwd(), './src/' + component + 's' + '/' + process.argv[4] + '.' + norkcfg.lang)
try {
fs.copySync(src, dest, { overwrite: false, errorOnExist: true })
} catch (err) {
return logError(err.message)
}
return logSuccess()
}
if (component == 'model') {
let src = path.join(__dirname, './make-files/express-' + norkcfg.lang + '/' + component + '.js')
let dest = path.join(process.cwd(), './src/' + component + 's' + '/' + process.argv[4] + '.js')
try {
fs.copySync(src, dest, { overwrite: false, errorOnExist: true })
} catch (err) {
return logError(err.message)
}
return logSuccess()
}
if (component == 'view') {
let src = path.join(__dirname, './make-files/express-' + norkcfg.lang + '/' + component + '.ejs')
let dest = path.join(process.cwd(), './src/' + component + 's' + '/' + process.argv[4] + '.ejs')
try {
fs.copySync(src, dest, { overwrite: false, errorOnExist: true })
} catch (err) {
return logError(err.message)
}
return logSuccess()
}
if (component == 'test') {
let src = path.join(__dirname, './make-files/express-' + norkcfg.lang + '/' + component + '.js')
let dest = path.join(process.cwd(), './src/' + component + 's' + '/' + process.argv[4] + '.test.js')
try {
fs.copySync(src, dest, { overwrite: false, errorOnExist: true })
} catch (err) {
return logError(err.message)
}
return logSuccess()
}
}
if (process.argv[2] == 'setup') {
const questions = {
type: 'list',
message: "Pick the technology you're using:",
name: 'lang',
choices: [
{ name: 'Typescript', value: 'ts' },
{ name: 'Javascript', value: 'js' },
],
}
let answers = await inquirer.prompt(questions)
fs.writeJsonSync(path.join(process.cwd(), './norkconfig.json'), answers)
return logSuccess()
}
if (process.argv[2] == '-v' || process.argv[2] == '--version') {
const pkgJson = require(path.join(__dirname, '../package.json'))
return console.log('nork', pkgJson.version)
}
if (process.argv[2] == 'help' || process.argv[2] == '-h' || process.argv[2] == '--help') {
if (process.argv[3]) {
return logHelp(process.argv[3])
}
return logHelp()
}
process.argv.splice(0, 2)
logHelp(false, process.argv.join(' '))
})()

10
src/app.ts Normal file
View File

@@ -0,0 +1,10 @@
//import express from "express"
//import morgan from "morgan"
//export const app = express()
//app.use(morgan('dev'))
import Log from "./modules/LogService"
import Env from "./modules/Environment"
export { Log, Env }

View File

@@ -1,8 +0,0 @@
const root_get = (req, res) => {
res.render('home')
return true
}
module.exports = {
root_get,
}

View File

@@ -1,10 +0,0 @@
const { Router } = require('express')
const router = Router()
router.use((req, res, next) => {
console.log('Hi :)')
next()
})
module.exports = router

View File

@@ -1,17 +0,0 @@
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const modelSchema = new Schema(
{
title: {
type: String,
required: true,
},
},
{
timestamps: true,
},
)
const ModelName = mongoose.model('ModelName', modelSchema)
module.exports = ModelName

View File

@@ -1,8 +0,0 @@
const { Router } = require('express')
const rootController = require('../controllers/rootController')
const router = Router()
router.get('/', rootController.root_get)
module.exports = router

View File

@@ -1,9 +0,0 @@
const { getReq, getRes } = require('./modules/reqRes.module.js')
const { root_get } = require('../controllers/rootController.ts')
test('Home page render test', () => {
const req = getReq()
const res = getRes()
expect(root_get(req, res)).toBe(true)
})

View File

@@ -1,15 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>New Project</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Open+Sans&display=swap" rel="stylesheet">
</head>
<body>
</body>
</html>

View File

@@ -1,10 +0,0 @@
import { Request, Response } from 'express'
const root_get = (req: Request, res: Response) => {
res.render('home')
return true
}
module.exports = {
root_get,
}

View File

@@ -1,10 +0,0 @@
import { Router, Request, Response, NextFunction } from 'express'
const router = Router()
router.use((req: Request, res: Response, next: NextFunction) => {
console.log('Hi :)')
next()
})
module.exports = router

View File

@@ -1,17 +0,0 @@
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const modelSchema = new Schema(
{
title: {
type: String,
required: true,
},
},
{
timestamps: true,
},
)
const ModelName = mongoose.model('ModelName', modelSchema)
module.exports = ModelName

View File

@@ -1,8 +0,0 @@
import { Router } from 'express'
const rootController = require('../controllers/rootController')
const router = Router()
router.get('/', rootController.root_get)
module.exports = router

View File

@@ -1,9 +0,0 @@
const { getReq, getRes } = require('./modules/reqRes.module.js')
const { root_get } = require('../controllers/rootController.ts')
test('Home page render test', () => {
const req = getReq()
const res = getRes()
expect(root_get(req, res)).toBe(true)
})

View File

@@ -1,15 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>New Project</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Open+Sans&display=swap" rel="stylesheet">
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,73 @@
import path from 'path'
import fs from 'fs-extra'
import Log from '../modules/LogService'
import dotenv from 'dotenv'
export default class Environment {
static get(env_path: string) {
console.log('ENV PATH:', env_path)
if(!fs.existsSync(env_path)) {
console.log('env_path = ', env_path)
Log.error(500, `.env file for ${process.env.NODE_ENV ? process.env.NODE_ENV : ''} environment does not exists`)
process.exit()
}
const norkcfg_path = path.join(path.dirname(env_path), '../norkconfig.json')
if(!fs.existsSync(norkcfg_path)) {
console.log('norkcfg_path = ', env_path)
Log.error(500, `norkcfg file does not exists`)
process.exit()
}
dotenv.config({ path: env_path })
const norkcfg = fs.readJSONSync(norkcfg_path)
if (norkcfg.database) {
if (norkcfg.database.db == 'postgresql') {
if (!process.env.DB_PORT) {
process.env.DB_PORT = '5432'
}
if (!process.env.DB_HOST) {
process.env.DB_HOST = '127.0.0.1'
}
if (!process.env.DB_USERNAME || !process.env.DB_PASSWORD || !process.env.DB_DATABASE) {
Log.error(500, 'missing DB parameters in .env file')
process.exit()
}
}
}
if (process.env.JWT_SECRET === undefined || process.env.JWT_SECRET == '') {
Log.error(500, 'JWT_SECRET is not set!')
process.exit()
}
return {
// General
APP_PORT: Number(process.env.APP_PORT),
APP_HOST: String(process.env.APP_HOST),
APP_HOSTNAME: process.env.APP_HOSTNAME !== undefined ? String(process.env.APP_HOSTNAME) : null,
CORS_WHITELIST: String(process.env.CORS_WHITELIST),
JWT_SECRET: String(process.env.JWT_SECRET),
// MongoDB
DB_URI: String(process.env.DB_URI),
// PostgreSQL
DB_PORT: Number(process.env.DB_PORT),
DB_HOST: String(process.env.DB_HOST),
DB_USERNAME: String(process.env.DB_USERNAME),
DB_PASSWORD: String(process.env.DB_PASSWORD),
DB_DATABASE: String(process.env.DB_DATABASE),
// Nork
NORK: norkcfg,
// SMTP
SMTP_HOST: String(process.env.SMTP_HOST),
SMTP_USER: String(process.env.SMTP_USER),
SMTP_PASS: String(process.env.SMTP_PASS),
SMTP_FROM: String(process.env.SMTP_FROM)
}
}
}

45
src/modules/LogService.ts Normal file
View File

@@ -0,0 +1,45 @@
import colors from 'colors'
import fs from 'fs'
import path from 'path'
export default class Log {
public static info(code: number, message: string, data?: any): object {
if (!data) {
data = ''
}
console.log(colors.bgGreen.black(` ${code} `) + colors.green.bgBlack(` ${message} `) + data)
//this.writeLog('info', code, message, data)
return {
code: code,
message: message,
data: data
}
}
public static error(code: number, message: string, data?: any): object {
if (!data) {
data = ''
}
console.log(colors.bgRed.black(` ${code} `) + colors.red.bgBlack(` ${message} `) + data)
//this.writeLog('error', code, message, data)
return {
code: code,
message: message,
data: data
}
}
private static writeLog(level: string, code: number, message: string, data?: any): void {
if (data) {
data = JSON.stringify(data)
}
try {
throw Error('nevim')
} catch (error) {
this.error(500, 'Error while writing to log file', error)
return
}
}
}

View File

@@ -1,2 +0,0 @@
APP_PORT = 8080
DB_URI = 'mongodb://username:password@localhost:27017/database?authSource=admin'

View File

@@ -1,107 +0,0 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# package lock file
package-lock.json

View File

@@ -1,3 +0,0 @@
{
"lang": "js"
}

View File

@@ -1,24 +0,0 @@
{
"name": "project-name",
"version": "1.0.0",
"description": "",
"main": "src/app.js",
"scripts": {
"start": "node src/app.js",
"dev": "nodemon src/app.js",
"test": "jest"
},
"author": "",
"license": "ISC",
"dependencies": {
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"ejs": "^3.1.6",
"express": "^4.17.1",
"mongoose": "^5.12.3",
"morgan": "^1.10.0"
},
"devDependencies": {
"jest": "^27.0.6"
}
}

View File

@@ -1,41 +0,0 @@
const express = require('express')
const morgan = require('morgan')
const mongoose = require('mongoose')
const dotenv = require('dotenv').config()
const cors = require('cors')
const path = require('path')
const routes = require('./routes')
const middlewares = require('./middlewares')
const port = process.env.APP_PORT || 8080
const app = express()
// MongoDB
const dbURI = process.env.DB_URI
mongoose
.connect(dbURI, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true })
.then(result => {
console.log('connected to db')
app.listen(port, () => {
console.log(`server is running on http://localhost:${port}`)
})
})
.catch(err => {
console.log(err)
})
// View engine
app.set('view engine', 'ejs')
// Middlewares
app.use(middlewares)
app.set('views', path.join(__dirname, 'views'))
app.use(express.static(path.join(__dirname, 'public')))
app.use(cors())
app.use(morgan('dev'))
app.use(express.urlencoded({ extended: true }))
app.use(express.json())
// Routes
app.use(routes)

View File

@@ -1,8 +0,0 @@
const root_get = (req, res) => {
res.render('home')
return true
}
module.exports = {
root_get,
}

View File

@@ -1,8 +0,0 @@
const { Router } = require('express')
const sayHiMiddleware = require('./sayHiMiddleware')
const router = Router()
router.use(sayHiMiddleware)
module.exports = router

View File

@@ -1,10 +0,0 @@
const { Router } = require('express')
const router = Router()
router.use((req, res, next) => {
console.log('Hi :)')
next()
})
module.exports = router

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.8 KiB

View File

@@ -1,13 +0,0 @@
const { Router } = require('express')
const rootRoutes = require('./rootRoutes')
const router = Router()
router.use(rootRoutes)
// 404
router.use((req, res) => {
res.status(404).send('E404')
})
module.exports = router

View File

@@ -1,8 +0,0 @@
const { Router } = require('express')
const rootController = require('../controllers/rootController')
const router = Router()
router.get('/', rootController.root_get)
module.exports = router

View File

@@ -1,9 +0,0 @@
const { getReq, getRes } = require('./modules/reqRes.module.js')
const { root_get } = require('../controllers/rootController.js')
test('Home page render test', () => {
const req = getReq()
const res = getRes()
expect(root_get(req, res)).toBe(true)
})

View File

@@ -1,16 +0,0 @@
module.exports.getReq = () => {
const req = {}
req.body = {}
return req
}
module.exports.getRes = () => {
const res = {}
res.locals = {}
res.status = () => res
res.json = () => res
res.send = () => res
res.render = () => res
return res
}

View File

@@ -1 +0,0 @@
# Folder for utils and other config files

View File

@@ -1,69 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>New Project</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Open+Sans&display=swap" rel="stylesheet">
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Open Sans', sans-serif;
}
.content {
width: 100vw;
height: 100vh;
display: flex;
justify-content: space-between;
padding-top: 5rem;
flex-direction: column;
}
footer, .welcome {
display: flex;
justify-content: center;
}
.welcome {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
img {
width: 200px;
padding-top: 2rem;
}
footer {
padding-bottom: 2rem;
text-align: center;
}
.logos {
display: flex;
align-items: center;
gap: 1rem;
}
</style>
</head>
<body>
<div class="content">
<div class="welcome">
<h1>Let's make something amazing!</h1>
<div class="logos">
<img src="/nodejs_logo.svg" alt="node.js logo">
<img src="/expressjs.png" alt="express.js logo">
</div>
</div>
<footer>
<div class="author">
<p>Made by </p><a href="http://www.filiprojek.cz">filiprojek.cz</a>
</div>
</footer>
</div>
</body>
</html>

View File

@@ -1,107 +0,0 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# package lock file
package-lock.json

View File

@@ -1 +0,0 @@
# New Project

View File

@@ -1,5 +0,0 @@
/** @type {import('@ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};

View File

@@ -1,3 +0,0 @@
{
"lang": "ts"
}

View File

@@ -1,45 +0,0 @@
{
"name": "project-name",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"start": "node dist/app.js",
"dev": "nodemon src/app.ts",
"test": "jest",
"clean": "rimraf dist/*",
"copy-assets": "ts-node src/utils/copyAssets",
"tsc": "tsc -p .",
"build": "npm-run-all clean tsc copy-assets"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"ejs": "^3.1.6",
"express": "^4.17.1",
"mongoose": "^5.12.3",
"morgan": "^1.10.0",
"fs-extra": "^10.0.0"
},
"devDependencies": {
"@types/cors": "^2.8.10",
"@types/ejs": "^3.0.6",
"@types/express": "^4.17.11",
"@types/fs-extra": "^9.0.12",
"@types/jest": "^26.0.24",
"@types/mongoose": "^5.10.5",
"@types/morgan": "^1.9.2",
"@types/node": "^14.14.41",
"@types/shelljs": "^0.8.9",
"jest": "^27.0.6",
"npm-run-all": "^4.1.5",
"rimraf": "^3.0.2",
"shelljs": "^0.8.4",
"ts-jest": "^27.0.4",
"ts-node": "^9.1.1",
"typescript": "^4.2.4"
}
}

View File

@@ -1,2 +0,0 @@
APP_PORT = 8080
DB_URI = 'mongodb://username:password@localhost:27017/database?authSource=admin'

View File

@@ -1,43 +0,0 @@
import express from 'express'
import morgan from 'morgan'
import mongoose from 'mongoose'
import path from 'path'
import cors from 'cors'
const config = require('./utils/environment')
const routes = require('./routes')
const middlewares = require('./middlewares')
const port: Number = config.APP_PORT || 8080
const app = express()
// MongoDB
const dbURI: string = config.DB_URI
mongoose
.connect(dbURI, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
})
.then(result => {
console.log('connected to db')
app.listen(port, () => {
console.log(`Server is listening on http://localhost:${port}`)
})
})
.catch(err => {
console.log(err)
})
// Middlewares
app.use(middlewares)
app.set('view engine', 'ejs')
app.set('views', path.join(__dirname, 'views'))
app.use(cors())
app.use(morgan('dev'))
app.use(express.urlencoded({ extended: true }))
app.use(express.json())
app.use(express.static(path.join(__dirname, 'public')))
// Routes
app.use(routes)

View File

@@ -1,10 +0,0 @@
import { Request, Response } from 'express'
const root_get = (req: Request, res: Response) => {
res.render('home')
return true
}
module.exports = {
root_get,
}

View File

@@ -1,8 +0,0 @@
import { Router } from 'express'
const sayHiMiddleware = require('./sayHiMiddleware')
const router = Router()
router.use(sayHiMiddleware)
module.exports = router

View File

@@ -1,11 +0,0 @@
import { Router, Request, Response, NextFunction } from 'express'
const router = Router()
router.use((req: Request, res: Response, next: NextFunction) => {
console.log('Hi :)')
next()
})
module.exports = router

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.8 KiB

View File

@@ -1,13 +0,0 @@
import { Router } from 'express'
const rootRoutes = require('./rootRoutes')
const router = Router()
router.use(rootRoutes)
// 404
router.use((req, res) => {
res.status(404).send('E404')
})
module.exports = router

View File

@@ -1,8 +0,0 @@
import { Router } from 'express'
const rootController = require('../controllers/rootController')
const router = Router()
router.get('/', rootController.root_get)
module.exports = router

View File

@@ -1,9 +0,0 @@
const { getReq, getRes } = require('./modules/reqRes.module.js')
const { root_get } = require('../controllers/rootController.ts')
test('Home page render test', () => {
const req = getReq()
const res = getRes()
expect(root_get(req, res)).toBe(true)
})

View File

@@ -1,16 +0,0 @@
module.exports.getReq = () => {
const req = {}
req.body = {}
return req
}
module.exports.getRes = () => {
const res = {}
res.locals = {}
res.status = () => res
res.json = () => res
res.send = () => res
res.render = () => res
return res
}

View File

@@ -1,6 +0,0 @@
import * as shell from 'shelljs'
// Copy all the view templates
shell.cp('-R', 'src/views', 'dist/')
shell.cp('-R', 'src/public', 'dist/')
shell.cp('-u', 'src/.env', 'dist/')

View File

@@ -1,7 +0,0 @@
import path from 'path'
require('dotenv').config({ path: path.join(__dirname, '../.env') })
module.exports = {
APP_PORT: process.env.APP_PORT,
DB_URI: process.env.DB_URI,
}

View File

@@ -1,69 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>New Project</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Open+Sans&display=swap" rel="stylesheet">
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Open Sans', sans-serif;
}
.content {
width: 100vw;
height: 100vh;
display: flex;
justify-content: space-between;
padding-top: 5rem;
flex-direction: column;
}
footer, .welcome {
display: flex;
justify-content: center;
}
.welcome {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
img {
width: 200px;
padding-top: 2rem;
}
footer {
padding-bottom: 2rem;
text-align: center;
}
.logos {
display: flex;
align-items: center;
gap: 1rem;
}
</style>
</head>
<body>
<div class="content">
<div class="welcome">
<h1>Let's make something amazing!</h1>
<div class="logos">
<img src="/nodejs_logo.svg" alt="node.js logo">
<img src="/expressjs.png" alt="express.js logo">
</div>
</div>
<footer>
<div class="author">
<p>Made by </p><a href="http://www.filiprojek.cz">filiprojek.cz</a>
</div>
</footer>
</div>
</body>
</html>

View File

@@ -1,71 +0,0 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./dist", /* Redirect output structure to the directory. */
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
// "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}

3
src/utils/copyAssets.ts Normal file
View File

@@ -0,0 +1,3 @@
import * as shell from 'shelljs'
shell.chmod('+x', 'dist/app.js')

15
tsconfig.json Normal file
View File

@@ -0,0 +1,15 @@
{
"compilerOptions": {
"target": "es6" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
"module": "commonjs" /* Specify what module code is generated. */,
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
"rootDir": "./src" /* Specify the root folder within your source files. */,
"strict": true /* Enable all strict type-checking options. */,
"baseUrl": "./" /* Base directory to resolve non-absolute module names. */,
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */,
"skipLibCheck": true /* Skip type checking all .d.ts files. */,
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
"declaration": true
},
"exclude": ["_old", "node_modules", "src/make-files", "src/skeletons", "src/tests", "src/interfaces", "src/utils"]
}