6 Commits

Author SHA1 Message Date
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
46 changed files with 850 additions and 406 deletions

View File

@@ -3,27 +3,16 @@
"es2021": true, "es2021": true,
"node": true "node": true
}, },
"extends": [ "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser", "parser": "@typescript-eslint/parser",
"parserOptions": { "parserOptions": {
"ecmaVersion": 6, "ecmaVersion": 6,
"sourceType": "module" "sourceType": "module"
}, },
"plugins": [ "plugins": ["@typescript-eslint"],
"@typescript-eslint"
],
"rules": { "rules": {
"indent": [ "indent": ["error", "tab"],
"error", "linebreak-style": ["error", "unix"],
"tab"
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [ "quotes": [
"error", "error",
"single", "single",
@@ -31,9 +20,6 @@
"allowTemplateLiterals": true "allowTemplateLiterals": true
} }
], ],
"semi": [ "semi": ["error", "never"]
"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

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]

View File

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

View File

@@ -1,6 +1,6 @@
{ {
"name": "nork", "name": "nork",
"version": "3.0.4", "version": "3.0.5",
"description": "The best node.js 'framework' :)", "description": "The best node.js 'framework' :)",
"main": "dist/app.js", "main": "dist/app.js",
"bin": "dist/app.js", "bin": "dist/app.js",
@@ -14,7 +14,8 @@
"copy-assets": "ts-node src/utils/copyAssets", "copy-assets": "ts-node src/utils/copyAssets",
"build": "npm-run-all clean tsc copy-assets", "build": "npm-run-all clean tsc copy-assets",
"test": "mocha --config .mocharc.json --watch src/**/*.test.ts", "test": "mocha --config .mocharc.json --watch src/**/*.test.ts",
"prepublish": "npm-run-all build" "prepublish": "npm-run-all build",
"format": "npx prettier --write ."
}, },
"keywords": [ "keywords": [
"node", "node",
@@ -25,7 +26,7 @@
"author": "Filip Rojek", "author": "Filip Rojek",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"colors":"1.4.0", "colors": "1.4.0",
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
"inquirer": "^8.1.2", "inquirer": "^8.1.2",
"pad": "^3.2.0" "pad": "^3.2.0"
@@ -42,6 +43,7 @@
"eslint": "^8.3.0", "eslint": "^8.3.0",
"mocha": "^9.1.3", "mocha": "^9.1.3",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"prettier": "^2.7.1",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"shelljs": "^0.8.5", "shelljs": "^0.8.5",
"ts-node": "^10.4.0", "ts-node": "^10.4.0",

View File

@@ -1,13 +1,17 @@
/* spell-checker: disable */ /_ spell-checker: disable _/
# Todo: # Todo:
- [ ] auth jwt refresh token based system - [ ] auth jwt refresh token based system
- https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/ - https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/
- [ ] version of nork control - [ ] version of nork control
- [ ] upgrade to newer version system - [ ] 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 ### 11-24-2021
- zacal jsem predelavat nork do OOP - zacal jsem predelavat nork do OOP
- co jsem udelal: - co jsem udelal:
- [x] --help - [x] --help
@@ -19,6 +23,17 @@
- je treba dopsat par types a fixnout zbytek erroru - je treba dopsat par types a fixnout zbytek erroru
- zatim netestovana funkcnost - zatim netestovana funkcnost
### 1-10.2022 ### 1-10-2022
- dodelal jsem create a otestoval ho - dodelal jsem create a otestoval ho
- [x] create - [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

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

@@ -14,7 +14,7 @@ export default class Create {
{ {
type: 'input', type: 'input',
name: 'project_name', name: 'project_name',
message: 'Enter project name:', message: 'Enter project name:'
}, },
{ {
type: 'list', type: 'list',
@@ -22,47 +22,75 @@ export default class Create {
name: 'lang', name: 'lang',
choices: [ choices: [
{ name: 'Typescript', value: 'ts' }, { name: 'Typescript', value: 'ts' },
{ name: 'Javascript', value: 'js' }, { name: 'Javascript - DEPRECATED', value: 'js' }
], ]
},
{
type: 'list',
message: `Pick the database & ORM you're using:`,
name: 'db',
choices: [
{ name: 'MongoDB - Mongoose', value: { db: 'mongodb', orm: 'mongoose' } },
{ name: 'MySQL - Sequelize', value: { db: 'mysql', orm: 'sequelize' } },
{ name: 'PostgreSQL - Sequelize', value: { db: 'postgresql', orm: 'sequelize' } }
]
}, },
{ {
type: 'input', type: 'input',
name: 'author', name: 'author',
message: 'Enter your name:', message: 'Enter your name:'
}, },
{
type: 'input',
name: 'email',
message: 'Enter your email:'
},
{
type: 'input',
name: 'website',
message: 'Enter your website:'
}
] ]
// remove first question if project name is already known // remove first question if project name is already known
if (projectName) { if (projectName) questions.shift()
questions.shift()
}
const answers = await inquirer.prompt(questions) const answers = await inquirer.prompt(questions)
const data: CreateInterface = { const data: CreateInterface = {
project_name: answers.project_name ? answers.project_name : process.argv[3], project_name: answers.project_name ? answers.project_name : process.argv[3],
lang: answers.lang, lang: answers.lang,
author: answers.author, author: answers.author,
database: answers.db,
website: answers.website,
email: answers.email
} }
// copy skeleton to new project // copy skeleton to new project
process.argv.includes('-i') ? (projectPath = process.cwd()) : (projectPath = path.join(process.cwd(), data.project_name)) process.argv.includes('-i') ? (projectPath = process.cwd()) : (projectPath = path.join(process.cwd(), data.project_name))
fs.copySync(path.join(__dirname, './skeletons/express-' + data.lang), projectPath) fs.copySync(path.join(__dirname, './skeletons/express-' + data.lang), projectPath)
// copy default db models to new project
if (data.database.orm == 'mongoose') fs.copySync(path.join(__dirname, './skeletons/mongoose-models/'), projectPath + '/src/models')
if (data.database.orm == 'sequelize') fs.copySync(path.join(__dirname, './skeletons/sequelize-models/'), projectPath + '/src/models')
// edit package.json file // edit package.json file
const pkgJson = fs.readJsonSync(path.join(projectPath, 'package.json')) const pkgJson = fs.readJsonSync(path.join(projectPath, 'package.json'))
// const pkgJson = require(path.join(projectPath, 'package.json'))
pkgJson.name = data.project_name pkgJson.name = data.project_name
pkgJson.author = data.author pkgJson.author = `${data.author} <${data.email}> (${data.website})`
fs.writeFile(path.join(projectPath, 'package.json'), JSON.stringify(pkgJson, null, 2), (err) => {
fs.writeFile(path.join(projectPath, 'package.json'), JSON.stringify(pkgJson, null, 2), err => {
if (err) return global.logError(err.message) if (err) return global.logError(err.message)
}) })
// create norkconfig.json
const norkconfig: any = { ...data }
norkconfig['version'] = require('../package.json').version
fs.writeFileSync(path.join(projectPath, 'norkconfig.json'), JSON.stringify(norkconfig, null, 2))
console.log(colors.yellow('Project settings')) console.log(colors.yellow('Project settings'))
console.log(colors.yellow('------------------')) console.log(colors.yellow('------------------'))
console.log(pad(colors.gray('Project name: '), 30), data.project_name) 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('Author: '), 30), pkgJson.author)
console.log(pad(colors.gray('Language: '), 30), global.langToLanguage(String(data.lang))) console.log(pad(colors.gray('Language: '), 30), global.langToLanguage(String(data.lang)))
console.log(pad(colors.gray('Database: '), 30), global.dbToDatabase(String(data.database.db)))
return global.logSuccess(`Project ${data.project_name} created successfully!`) return global.logSuccess(`Project ${data.project_name} created successfully!`)
} }

View File

@@ -24,4 +24,17 @@ export default class Global {
return 'Unknown language' return 'Unknown language'
} }
} }
static dbToDatabase(lang: string): string {
switch (lang) {
case 'mongodb':
return 'MongoDB'
case 'postgresql':
return 'PostgreSQL'
case 'mysql':
return 'MySQL'
default:
return 'Unknown database'
}
}
} }

View File

@@ -1,5 +1,13 @@
interface database {
db: string
orm: string
}
export interface Create { export interface Create {
project_name: string project_name: string
author: string author: string
lang: string lang: string
database: database
email: string
website: string
} }

View File

@@ -10,6 +10,6 @@ export interface Questions {
{ {
name: string name: string
value: string value: string
}, }
] ]
} }

View File

@@ -4,5 +4,5 @@ const root_get = (req, res) => {
} }
module.exports = { module.exports = {
root_get, root_get
} }

View File

@@ -5,12 +5,12 @@ const modelSchema = new Schema(
{ {
title: { title: {
type: String, type: String,
required: true, required: true
}, }
}, },
{ {
timestamps: true, timestamps: true
}, }
) )
const ModelName = mongoose.model('ModelName', modelSchema) const ModelName = mongoose.model('ModelName', modelSchema)

View File

@@ -4,12 +4,12 @@ const modelSchema = new Schema<any>(
{ {
title: { title: {
type: String, type: String,
required: true, required: true
}, }
}, },
{ {
timestamps: true, timestamps: true
}, }
) )
export default model('ModelName', modelSchema) export default model('ModelName', modelSchema)

View File

@@ -13,8 +13,8 @@ export default class Setup {
name: 'lang', name: 'lang',
choices: [ choices: [
{ name: 'Typescript', value: 'ts' }, { name: 'Typescript', value: 'ts' },
{ name: 'Javascript', value: 'js' }, { name: 'Javascript', value: 'js' }
], ]
} }
const answers = await inquirer.prompt(Object(questions)) const answers = await inquirer.prompt(Object(questions))
fs.writeJsonSync(path.join(process.cwd(), './norkconfig.json'), answers) fs.writeJsonSync(path.join(process.cwd(), './norkconfig.json'), answers)

View File

@@ -15,13 +15,13 @@ const app = express()
const dbURI = process.env.DB_URI const dbURI = process.env.DB_URI
mongoose mongoose
.connect(dbURI, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true }) .connect(dbURI, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true })
.then(result => { .then((result) => {
console.log('connected to db') console.log('connected to db')
app.listen(port, () => { app.listen(port, () => {
console.log(`server is running on http://localhost:${port}`) console.log(`server is running on http://localhost:${port}`)
}) })
}) })
.catch(err => { .catch((err) => {
console.log(err) console.log(err)
}) })

View File

@@ -4,5 +4,5 @@ const root_get = (req, res) => {
} }
module.exports = { module.exports = {
root_get, root_get
} }

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

View File

@@ -1,5 +1,5 @@
# Logs # Logs
logs #logs
*.log *.log
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*

View File

@@ -1,20 +1,15 @@
{ {
"arrowParens": "avoid",
"bracketSpacing": true,
"endOfLine": "lf",
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
"jsxBracketSameLine": true,
"jsxSingleQuote": true,
"printWidth": 200,
"proseWrap": "preserve",
"quoteProps": "as-needed",
"requirePragma": false,
"semi": false,
"singleQuote": true,
"tabWidth": 4, "tabWidth": 4,
"trailingComma": "all",
"useTabs": true, "useTabs": true,
"singleQuote": true,
"semi": false,
"trailingComma": "none",
"jsxSingleQuote": true,
"jsxBracketSameLine": true,
"printWidth": 200,
"bracketSpacing": true,
"vueIndentScriptAndStyle": true, "vueIndentScriptAndStyle": true,
"parser": "typescript" "arrowParens": "always",
"bracketSameLine": false,
"endOfLine": "lf"
} }

View File

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

View File

@@ -1,4 +1,5 @@
{ {
"lang": "ts", "lang": "ts",
"db": "" "db": "",
"orm": ""
} }

View File

@@ -2,20 +2,22 @@
"name": "project-name", "name": "project-name",
"version": "1.0.0", "version": "1.0.0",
"description": "", "description": "",
"main": "app.js", "main": "dist/server.js",
"scripts": { "private": "true",
"start": "node -r tsconfig-paths/register -r ts-node/register dist/server.js",
"start:dev": "npx nodemon src/server.ts",
"dev": "nodemon src/server.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": [], "keywords": [],
"author": "", "author": "",
"repository": "github:username/repo",
"license": "ISC", "license": "ISC",
"scripts": {
"start": "node dist/server.js",
"start:dev": "nodemon src/server.ts",
"test": "jest",
"clean": "rimraf dist/*",
"copy-assets": "npx ts-node src/utils/copyAssets",
"tsc": "tsc -p .",
"build": "npm-run-all clean tsc copy-assets",
"format": "npx prettier --write ."
},
"dependencies": { "dependencies": {
"colors": "1.4.0", "colors": "1.4.0",
"cookie-parser": "^1.4.5", "cookie-parser": "^1.4.5",
@@ -23,11 +25,10 @@
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"ejs": "^3.1.6", "ejs": "^3.1.6",
"express": "^4.17.1", "express": "^4.17.1",
"express-validator": "^6.14.0", "express-validator": "^6.14.2",
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"mongoose": "^5.12.3", "mongoose": "^5.12.3",
"morgan": "^1.10.0",
"pg": "^8.7.1", "pg": "^8.7.1",
"pg-hstore": "^2.3.4", "pg-hstore": "^2.3.4",
"sequelize": "^6.15.0" "sequelize": "^6.15.0"
@@ -38,7 +39,7 @@
"@types/ejs": "^3.0.6", "@types/ejs": "^3.0.6",
"@types/express": "^4.17.11", "@types/express": "^4.17.11",
"@types/fs-extra": "^9.0.12", "@types/fs-extra": "^9.0.12",
"@types/jest": "^27.0.1", "@types/jest": "^27.5.2",
"@types/jsonwebtoken": "^8.5.8", "@types/jsonwebtoken": "^8.5.8",
"@types/mongoose": "^5.10.5", "@types/mongoose": "^5.10.5",
"@types/morgan": "^1.9.2", "@types/morgan": "^1.9.2",
@@ -48,10 +49,14 @@
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"shelljs": "^0.8.4", "shelljs": "^0.8.4",
"ts-jest": "^27.0.5", "ts-jest": "^27.1.5",
"ts-node": "^9.1.1", "ts-node": "^10.8.1",
"tsconfig-paths": "^3.11.0", "typescript": "^4.2.4",
"typescript": "^4.2.4" "morgan": "^1.10.0"
},
"jest": {
"preset": "ts-jest",
"testEnvironment": "node"
}, },
"nodemonConfig": { "nodemonConfig": {
"ignore": [ "ignore": [
@@ -63,7 +68,6 @@
"watch": [ "watch": [
"src" "src"
], ],
"exec": "node -r tsconfig-paths/register -r ts-node/register ./src/server.ts",
"ext": "ts, js" "ext": "ts, js"
} }
} }

View File

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

View File

@@ -2,8 +2,11 @@
APP_PORT = 6060 APP_PORT = 6060
APP_HOSTNAME = 'localhost' APP_HOSTNAME = 'localhost'
APP_HOST = 'http://localhost:8080' # frontend url APP_HOST = 'http://localhost:8080' # frontend url
CORS_WHITELIST = http://172.15.46.21:8080;http://192.168.0.1:8080
# Timezone
TZ = 'Europe/Prague'
CORS_WHITELIST = http://172.15.46.21:8080;http://192.168.0.1:8080
JWT_SECRET = '' JWT_SECRET = ''
# MongoDB # MongoDB
@@ -15,3 +18,9 @@ DB_HOST = '127.0.0.1'
DB_USERNAME = '' DB_USERNAME = ''
DB_PASSWORD = '' DB_PASSWORD = ''
DB_DATABASE = '' DB_DATABASE = ''
# SMTP
SMTP_HOST = ''
SMTP_USER = ''
SMTP_PASS = ''
SMTP_FROM = ''

View File

@@ -3,10 +3,16 @@ import morgan from 'morgan'
import path from 'path' import path from 'path'
import cors from 'cors' import cors from 'cors'
import cookieParser from 'cookie-parser' import cookieParser from 'cookie-parser'
import { router as routes } from '@/routes' import { router as routes } from './routes'
import { router as middlewares } from '@/middlewares' import { router as middlewares } from './middlewares'
import env from './config/environment'
const corsWhitelist = ['http://localhost:8080', 'http://localhost:6060'] export let corsWhitelist: Array<string>
if (env.CORS_WHITELIST != 'undefined') {
corsWhitelist = [...['http://localhost:8080', 'http://localhost:6040'], ...env.CORS_WHITELIST.split(';')]
} else {
corsWhitelist = ['http://localhost:8080', 'http://localhost:6040']
}
const corsOptions = { const corsOptions = {
origin: function (origin: any, callback: any) { origin: function (origin: any, callback: any) {
if (!origin || corsWhitelist.indexOf(origin) !== -1) { if (!origin || corsWhitelist.indexOf(origin) !== -1) {
@@ -16,7 +22,7 @@ const corsOptions = {
} }
}, },
optionsSuccessStatus: 200, optionsSuccessStatus: 200,
credentials: true, credentials: true
} }
export const app = express() export const app = express()

View File

@@ -1,22 +1,22 @@
import mongoose from 'mongoose' import mongoose from 'mongoose'
import config from '@/utils/environment' import env from './environment'
import { Err, Succ } from '@/services/globalService' import { Err, Succ } from '../services/globalService'
import db from '@/config/postgres.config' import db from './sequelize.config'
// MongoDB // MongoDB
const dbURI: string = config.DB_URI const dbURI: string = env.DB_URI
function connect() { function connect() {
if (!config.NORK.db) { if (!env.NORK.database) {
new Err(500, 'no database is in norkcfg.json') new Err(500, 'no database is in norkcfg.json')
return false return false
} }
if (config.NORK.db == 'mongodb') { if (env.NORK.database.orm == 'mongoose') {
mongoose mongoose
.connect(dbURI, { .connect(dbURI, {
useNewUrlParser: true, useNewUrlParser: true,
useUnifiedTopology: true, useUnifiedTopology: true,
useCreateIndex: true, useCreateIndex: true
}) })
.then(() => { .then(() => {
new Succ(200, 'connected to db') new Succ(200, 'connected to db')
@@ -28,7 +28,7 @@ function connect() {
}) })
} }
if (config.NORK.db == 'postgresql') { if (env.NORK.database.orm == 'sequelize') {
db.sync() db.sync()
.then(() => { .then(() => {
new Succ(200, 'connected to db') new Succ(200, 'connected to db')
@@ -40,8 +40,8 @@ function connect() {
}) })
} }
if (config.NORK.db.length > 0) { if (env.NORK.database.db.length > 0) {
new Err(500, `unsupported database ${config.NORK.db}`) new Err(500, `unsupported database ${env.NORK.database.db}`)
return false return false
} }
} }

View File

@@ -1,13 +1,14 @@
import path from 'path' import path from 'path'
import fs from 'fs-extra' import fs from 'fs-extra'
import { Err } from '@/services/globalService' import { Err } from '../services/globalService'
import dotenv from 'dotenv' import dotenv from 'dotenv'
const env_path = process.env.NODE_ENV ? `../.env.${process.env.NODE_ENV}` : '../.env'
dotenv.config({ path: path.join(__dirname, '../.env') }) dotenv.config({ path: path.join(__dirname, env_path) })
const norkcfg = fs.readJSONSync(path.join(__dirname, '../../norkconfig.json')) const norkcfg = fs.readJSONSync(path.join(__dirname, '../../norkconfig.json'))
if (norkcfg.db) { if (norkcfg.database) {
if (norkcfg.db == 'postgresql') { if (norkcfg.database.db == 'postgresql') {
if (!process.env.DB_PORT) { if (!process.env.DB_PORT) {
process.env.DB_PORT = '5432' process.env.DB_PORT = '5432'
} }
@@ -21,6 +22,18 @@ if (norkcfg.db) {
} }
} }
if (!fs.existsSync(path.join(__dirname, env_path))) {
console.log('$env_path = ', env_path)
console.log('$__dirname = ', __dirname)
new Err(500, `.env file for ${process.env.NODE_ENV ? process.env.NODE_ENV : ''} environment does not exists`)
process.exit()
}
if (process.env.JWT_SECRET === undefined || process.env.JWT_SECRET == '') {
new Err(500, 'JWT_SECRET is not set!')
process.exit()
}
export default { export default {
// General // General
APP_PORT: Number(process.env.APP_PORT), APP_PORT: Number(process.env.APP_PORT),
@@ -36,5 +49,11 @@ export default {
DB_USERNAME: String(process.env.DB_USERNAME), DB_USERNAME: String(process.env.DB_USERNAME),
DB_PASSWORD: String(process.env.DB_PASSWORD), DB_PASSWORD: String(process.env.DB_PASSWORD),
DB_DATABASE: String(process.env.DB_DATABASE), DB_DATABASE: String(process.env.DB_DATABASE),
// Nork
NORK: norkcfg, 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)
} }

View File

@@ -1,10 +0,0 @@
import { Sequelize } from 'sequelize'
import config from '@/utils/environment'
const db = new Sequelize(config.DB_DATABASE, config.DB_USERNAME, config.DB_PASSWORD, {
host: config.DB_HOST,
dialect: 'postgres',
logging: false,
})
export default db

View File

@@ -0,0 +1,10 @@
import { Sequelize } from 'sequelize'
import env from './environment'
const db = new Sequelize(env.DB_DATABASE, env.DB_USERNAME, env.DB_PASSWORD, {
host: env.DB_HOST,
dialect: 'postgres',
logging: false
})
export default db

View File

@@ -1,6 +1,6 @@
import { Request, Response } from 'express' import { Request, Response } from 'express'
export const root_get = (req: Request, res: Response) => { export function root_get(req: Request, res: Response) {
res.render('home') res.render('home')
return true return true
} }

View File

@@ -0,0 +1 @@
*.log

View File

@@ -1,24 +1,37 @@
import { Request, Response, NextFunction } from 'express' import { Request, Response, NextFunction } from 'express'
import jwt from 'jsonwebtoken' import jwt from 'jsonwebtoken'
import env from '@/utils/environment' import env from '../config/environment'
import { Err, Succ } from '@/services/globalService' import { Err, Succ } from '../services/globalService'
// import User from '@/models/User' // uncomment this import User from '../models/User' // uncomment this
export const requireAuth = (req: Request, res: Response, next: NextFunction) => { export function requireAuth(req: Request, res: Response, next: NextFunction) {
const token = req.cookies.jwt const token = req.cookies.jwt
new Err(500, 'uncomment code in authMiddleware before using!') new Err(500, 'uncomment code in authMiddleware before using!')
/* if (token) { if (token) {
jwt.verify(token, env.JWT_SECRET, async (err: any, decodedToken: any) => { jwt.verify(token, env.JWT_SECRET, async (err: any, decodedToken: any) => {
if (err) { if (err) {
// console.error(err.message) // console.error(err.message)
res.status(401).send(new Err(401, 'user is not authenticated')) res.status(401).json(new Err(401, 'user is not authenticated'))
} }
if (!err) { if (!err) {
const user = await User.findByPk(decodedToken.id) const user = (async () => {
if (env.NORK.db.orm) {
if (env.NORK.db.orm == 'sequelize') {
return await User.findByPk(decodedToken.id)
}
if (env.NORK.db.orm == 'mongoose') {
return await User.findById(decodedToken.id)
}
} else {
return null
}
})()
if (user === null) { if (user === null) {
res.status(401).send(new Err(401, 'user is not authenticated')) res.status(401).json(new Err(401, 'user is not authenticated'))
return return
} }
res.locals.user = user res.locals.user = user
new Succ(100, 'user is authenticated') new Succ(100, 'user is authenticated')
next() next()
@@ -27,6 +40,24 @@ export const requireAuth = (req: Request, res: Response, next: NextFunction) =>
} }
if (!token) { if (!token) {
res.status(401).send(new Err(401, 'user is not authenticated')) res.status(401).json(new Err(401, 'user is not authenticated'))
} */ }
}
export function requireVerified(req: Request, res: Response, next: NextFunction) {
if (res.locals.user._id) {
if (res.locals.user.verified) {
new Succ(100, 'user is verified')
next()
return
}
res.status(403).json(new Err(403, 'user is not verified'))
return
}
if (!res.locals.user._id) {
res.status(401).json(new Err(401, 'user is not authenticated'))
return
}
} }

View File

@@ -1,13 +1,16 @@
import { Request, Response, NextFunction } from 'express' import { Request, Response, NextFunction } from 'express'
import { validationResult } from 'express-validator' import { validationResult } from 'express-validator'
import { Err } from '../services/globalService'
class Middleware { class Middleware {
handleValidationError(req: Request, res: Response, next: NextFunction) { handleValidationError(req: Request, res: Response, next: NextFunction) {
const error = validationResult(req) const error = validationResult(req)
if (!error.isEmpty()) { if (!error.isEmpty()) {
return res.status(400).json(error.array()[0]) new Err(400, error)
return res.status(400).json(new Err(400, 'validation error', error.array()[0]))
} }
next() next()
} }
} }
export default new Middleware() export default new Middleware()

View File

@@ -1,6 +1,6 @@
import { Router } from 'express' import { Router } from 'express'
import { router as sayHiMiddleware } from '@/middlewares/sayHiMiddleware' import { router as sayHiMiddleware } from '../middlewares/sayHiMiddleware'
export const router = Router() export const router = Router()
router.use(sayHiMiddleware) // router.use(sayHiMiddleware)

View File

@@ -1,7 +1,7 @@
import { Router } from 'express' import { Router } from 'express'
import * as rootController from '@/controllers/rootController' import * as rootController from '../controllers/rootController'
import rootValidator from '@/validators/rootValidator' import rootValidator from '../validators/rootValidator'
import handleValidation from '@/middlewares/handleValidation' import handleValidation from '../middlewares/handleValidation'
export const router = Router() export const router = Router()
const mws = [handleValidation.handleValidationError] const mws = [handleValidation.handleValidationError]

View File

@@ -1,20 +1,20 @@
import http from 'http' import http from 'http'
import { app } from '@/app' import { app } from './app'
import config from '@/utils/environment' import env from './config/environment'
import { Succ } from '@/services/globalService' import { Succ } from './services/globalService'
import database from '@/config/database' import database from './config/database'
const port: number = config.APP_PORT || 8080 const port: number = env.APP_PORT || 8080
const hostname: string = config.APP_HOSTNAME || 'localhost' const hostname: string = env.APP_HOSTNAME || 'localhost'
const server = http.createServer(app) export const server = http.createServer(app)
// Server // Server
export function runServer(): void { export function runServer(): void {
server.listen(port, hostname, () => { server.listen(port, hostname, () => {
new Succ(200, `Server is listening on http://localhost:${port}`) new Succ(200, `Server is listening on http://${hostname}:${port}`)
}) })
} }
if (!config.NORK.db) { if (!env.NORK.database) {
runServer() runServer()
} else { } else {
const db_connection = database() const db_connection = database()

View File

@@ -1,21 +1,43 @@
import colors from 'colors' import colors from 'colors'
import { ErrType } from '@/interfaces/globalInterface' import fs from 'fs'
import path from 'path'
export interface ErrType {
code: number
message: string
data?: any
}
export class Err implements ErrType { export class Err implements ErrType {
code: number code: number
message: string message: string
data: any
constructor(code: number, message: string) { constructor(code: number, message: string | object, data: any = null) {
this.code = code this.code = code
this.message = message typeof message === 'object' ? (this.message = JSON.stringify(message)) : (this.message = message)
data ? (this.data = data) : false
// typeof data === 'object' ? (this.data = JSON.stringify(data)) : (this.data = data)
this.drop() this.drop()
} }
drop() { drop() {
console.log(colors.bgRed(`${this.code}`) + colors.bgBlack.red(` ${this.message}`)) if (this.data) {
console.log(colors.bgRed(`${this.code}`) + colors.bgBlack.red(` ${this.message}`) + this.data)
Log.make('Err', this.code, this.message, this.data)
return { return {
code: this.code, code: this.code,
message: this.message, message: this.message,
data: this.data
}
}
console.log(colors.bgRed(`${this.code}`) + colors.bgBlack.red(` ${this.message}`))
Log.make('Err', this.code, this.message)
return {
code: this.code,
message: this.message
} }
} }
} }
@@ -23,18 +45,129 @@ export class Err implements ErrType {
export class Succ { export class Succ {
code: number code: number
message: string message: string
data?: any
constructor(code: number, message: string) { constructor(code: number, message: string, data: any = null) {
this.code = code this.code = code
this.message = message this.message = message
data ? (this.data = data) : false
this.drop() this.drop()
} }
drop() { drop() {
console.log(colors.bgGreen.black(`${this.code}`) + colors.green.bgBlack(` ${this.message}`)) if (this.data) {
console.log(colors.bgGreen.black(`${this.code}`) + colors.green.bgBlack(` ${this.message}`) + this.data)
return { return {
code: this.code, code: this.code,
message: this.message, message: this.message,
data: this.data
}
}
console.log(colors.bgGreen.black(`${this.code}`) + colors.green.bgBlack(` ${this.message}`))
return {
code: this.code,
message: this.message
}
}
}
export interface LogType {
type: 'Err' | 'Succ' | 'Info'
code?: number
message?: string
data?: any
logFile?: string
}
export class Log implements LogType {
type: 'Err' | 'Succ' | 'Info'
code?: number
message?: string
data?: any
logFile?: string
/**
* @param type
* - Type of log
* - Err | Succ | Info
* @param code
* - not required
* - HTTP status code
* @param message
* - could be anything
* @param data
* - could be anything
* @param logFile
* - name of logFile
* - default is log type file
*/
constructor(type: 'Err' | 'Succ' | 'Info', code?: number, message?: string, data?: any, logFile?: string) {
this.type = type
this.code = code
this.message = message
this.data = data
this.logFile = logFile
if (!this.logFile) {
this.logFile = `${type}.global.log`
} else {
this.logFile = this.logFile + '.log'
}
this.logFile = path.join(__dirname, this.logFile)
}
static pathMake(type: string, name?: string) {
let logName
if (!name) {
logName = `${type}.global.log`
} else {
logName = name + '.log'
}
return path.join(__dirname, '../logs/' + logName)
}
/**
* returns current date in my custom format
*/
static dateNow(): string {
/**
* @param num: number
*
* receives number and returns two digits number
* example:
* input num = 9 => returns string 09
*/
function add0(num: number): string {
if (num.toString().length <= 1) {
return '0' + String(num)
}
return String(num)
}
const d = new Date()
return `${d.getFullYear()}-${add0(d.getMonth() + 1)}-${add0(d.getDate())} ${add0(d.getHours())}:${add0(d.getMinutes())}:${add0(d.getSeconds())}`
}
static make(type: 'Err' | 'Succ' | 'Info', code?: number, message?: string, data?: any, logFile?: string) {
let realPath = Log.pathMake(type, logFile)
let formattedData = `Date: "${Log.dateNow()}" Type: "${type}"`
code ? (formattedData += ` Code: "${code}"`) : false
message ? (formattedData += ` Message: "${message}"`) : false
if (data) {
if (typeof data === 'object') {
data = JSON.stringify(data)
}
formattedData += ` Data: "${data}"`
}
formattedData += '\n'
if (fs.existsSync(realPath)) {
fs.appendFileSync(realPath, formattedData)
} else {
fs.writeFileSync(realPath, formattedData)
} }
} }
} }

View File

@@ -4,8 +4,12 @@
/* Basic Options */ /* Basic Options */
// "incremental": true, /* Enable incremental compilation */ // "incremental": true, /* Enable incremental compilation */
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ "target": "es6",
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
/* 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. */ // "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */ // "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */ // "checkJs": true, /* Report errors in .js files. */
@@ -14,8 +18,11 @@
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */ // "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./dist", /* Redirect output structure to the directory. */ "outDir": "./dist",
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
/* 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 */ // "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */ // "removeComments": true, /* Do not emit comments to output. */
@@ -25,7 +32,8 @@
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */ /* Strict Type-Checking Options */
"strict": true, /* Enable all 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. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */ // "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */
@@ -34,52 +42,22 @@
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "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. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */ "baseUrl": "./",
// "noUnusedLocals": true, /* Report errors on unused locals. */ "esModuleInterop": true,
// "noUnusedParameters": true, /* Report errors on unused parameters. */ /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ "resolveJsonModule": true,
// "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": {
"@/*": ["src/","src/*"],
"@dist/*": ["dist/*"],
"@controllers/*": ["src/controllers/"],
"@interfaces/*": ["src/interfaces/*"],
"@middlewares/*": ["src/middlewares/*"],
"@models/*": ["src/models/*"],
"@public/*": ["src/public/*"],
"@routes/*": ["src/routes/*"],
"@services/*": ["src/services/*"],
"@test/*": ["src/test/*"],
"@utils/*": ["src/utils/*"],
"@validators/*": ["src/validators/*"],
"@views/*": ["src/views/*"],
},
// "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. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "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 */ /* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ "experimentalDecorators": true,
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ /* Enables experimental support for ES7 decorators. */
"emitDecoratorMetadata": true,
/* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */ /* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */ "skipLibCheck": true,
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ /* Skip type checking of declaration files. */
} "forceConsistentCasingInFileNames": true
/* Disallow inconsistently-cased references to the same file. */
},
"exclude": ["src/tests"]
} }

View File

@@ -0,0 +1,40 @@
import path from 'path'
import { Schema, model } from 'mongoose'
export const schemaName = path.basename(__filename).split('.')[0]
const schema = new Schema(
{
username: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
domains: [
{
role: Number,
domain_id: String
}
],
verification_code: {
type: Number,
length: 6
},
verified: {
type: Boolean,
default: false
}
},
{
timestamps: true
}
)
export default model(path.basename(__filename).split('.')[0], schema)

View File

@@ -0,0 +1,35 @@
import { DataTypes, Model } from 'sequelize'
import path from 'path'
import db from '../config/sequelize.config.ts'
class Instance extends Model {}
Instance.init(
{
_id: {
type: DataTypes.UUID,
primaryKey: true,
allowNull: false,
unique: true
},
username: {
type: DataTypes.STRING,
allowNull: false
},
password: {
type: DataTypes.STRING,
allowNull: false
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true
}
},
{
sequelize: db,
tableName: path.basename(__filename).split('.')[0].toLowerCase()
}
)
export default Instance

View File

@@ -1,23 +1,15 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "es6", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ "target": "es6" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
"module": "commonjs", /* Specify what module code is generated. */ "module": "commonjs" /* Specify what module code is generated. */,
"outDir": "./dist", /* Specify an output folder for all emitted files. */ "outDir": "./dist" /* Specify an output folder for all emitted files. */,
"rootDir": "./src", /* Specify the root folder within your source files. */ "rootDir": "./src" /* Specify the root folder within your source files. */,
"strict": true, /* Enable all strict type-checking options. */ "strict": true /* Enable all strict type-checking options. */,
"baseUrl": "./", /* Base directory to resolve non-absolute module names. */ "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. */ "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. */ "skipLibCheck": true /* Skip type checking all .d.ts files. */,
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
"declaration": true, "declaration": true
}, },
"exclude": [ "exclude": ["_old", "node_modules", "src/make-files", "src/skeletons", "src/tests", "src/interfaces", "src/utils"]
"_old",
"node_modules",
"src/make-files",
"src/skeletons",
"src/tests",
"src/interfaces",
"src/utils"
]
} }