first structure
This commit is contained in:
@@ -3,7 +3,6 @@ SECRET=fDS9j269DSfd823FhdfG65
|
|||||||
ACCESS_TOKEN_SECERT=PNd98dsDS089ds3SDh7C5hg265SFC42bgHxTg34x
|
ACCESS_TOKEN_SECERT=PNd98dsDS089ds3SDh7C5hg265SFC42bgHxTg34x
|
||||||
ACCESS_TOKEN_SECERT_ADMIN=G89dsJsd90DFdsf96F8se3sgL7JB29265SFC42bgHxTg34x
|
ACCESS_TOKEN_SECERT_ADMIN=G89dsJsd90DFdsf96F8se3sgL7JB29265SFC42bgHxTg34x
|
||||||
CONNECTION_STRING=
|
CONNECTION_STRING=
|
||||||
CONNECTION_STRING_LOCAL=mongodb://127.0.0.1:27017/delearn?authSource=admin
|
|
||||||
MERCHANT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
MERCHANT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||||
EMAIL_HOST=
|
EMAIL_HOST=
|
||||||
EMAIL_PORT=
|
EMAIL_PORT=
|
||||||
@@ -13,4 +12,7 @@ EMAIL_ADDRESS=
|
|||||||
SMS_USER=
|
SMS_USER=
|
||||||
SMS_PASS=
|
SMS_PASS=
|
||||||
SMS_NUMBER=
|
SMS_NUMBER=
|
||||||
URLIMAGE=https://api-delearn.iran.liara.run
|
URLIMAGE=https://api-delearn.iran.liara.run
|
||||||
|
MONGO_CONNECTION_HOST=127.0.0.1 mongodb://127.0.0.1:27017/delearn
|
||||||
|
MONGO_CONNECTION_PORT=27017
|
||||||
|
MONGO_CONNECTION_NAME=delearn
|
||||||
+66
-22
@@ -1,23 +1,67 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
root: true,
|
parser: '@typescript-eslint/parser',
|
||||||
env: {
|
parserOptions: {
|
||||||
browser: true,
|
project: 'tsconfig.json',
|
||||||
node: true,
|
sourceType: 'module',
|
||||||
jquery: true
|
},
|
||||||
},
|
plugins: ['@typescript-eslint/eslint-plugin'],
|
||||||
parserOptions: {
|
extends: [
|
||||||
parser: '@babel/eslint-parser',
|
'plugin:@typescript-eslint/recommended',
|
||||||
requireConfigFile: false
|
'plugin:prettier/recommended',
|
||||||
},
|
],
|
||||||
extends: ['@nuxtjs', 'plugin:nuxt/recommended', 'prettier'],
|
root: true,
|
||||||
plugins: [],
|
env: {
|
||||||
// add your custom rules here
|
node: true,
|
||||||
rules: {
|
jest: true,
|
||||||
'no-console': 'off',
|
},
|
||||||
camelcase: 'off',
|
ignorePatterns: ['.eslintrc.js'],
|
||||||
'no-async-promise-executor': 'off',
|
|
||||||
'vue/no-v-html': 'off',
|
rules: {
|
||||||
'vue/prop-name-casing': 'off'
|
'linebreak-style': 0,
|
||||||
}
|
strict: 0,
|
||||||
}
|
'max-len': ['error', { code: 120 }],
|
||||||
|
'quote-props': 'off',
|
||||||
|
'no-param-reassign': 'off',
|
||||||
|
'no-underscore-dangle': 'off',
|
||||||
|
'func-names': ['error', 'as-needed'],
|
||||||
|
'prefer-const': 'warn',
|
||||||
|
radix: 'off',
|
||||||
|
'no-restricted-syntax': ['error', "BinaryExpression[operator='at']"],
|
||||||
|
'no-await-in-loop': 'off',
|
||||||
|
'no-trailing-spaces': 'off',
|
||||||
|
'object-curly-spacing': 'off',
|
||||||
|
'object-curly-newline': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
ObjectExpression: {
|
||||||
|
multiline: true,
|
||||||
|
minProperties: 6,
|
||||||
|
consistent: true,
|
||||||
|
},
|
||||||
|
ObjectPattern: { multiline: true, minProperties: 6, consistent: true },
|
||||||
|
ImportDeclaration: {
|
||||||
|
multiline: true,
|
||||||
|
minProperties: 6,
|
||||||
|
consistent: true,
|
||||||
|
},
|
||||||
|
ExportDeclaration: {
|
||||||
|
multiline: true,
|
||||||
|
minProperties: 6,
|
||||||
|
consistent: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'global-require': 'off',
|
||||||
|
'import/no-dynamic-require': 'off',
|
||||||
|
'@typescript-eslint/interface-name-prefix': 'off',
|
||||||
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||||
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
'prettier/prettier': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
endOfLine: 'auto',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
# Auto detect text files and perform LF normalization
|
|
||||||
* text=auto
|
|
||||||
+39
-4
@@ -1,6 +1,41 @@
|
|||||||
|
# compiled output
|
||||||
|
/dist
|
||||||
/node_modules
|
/node_modules
|
||||||
.png
|
|
||||||
.jpg
|
|
||||||
.web
|
|
||||||
|
|
||||||
*.png
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
# package json
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Tests
|
||||||
|
/coverage
|
||||||
|
/.nyc_output
|
||||||
|
|
||||||
|
# IDEs and editors
|
||||||
|
/.idea
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.c9/
|
||||||
|
*.launch
|
||||||
|
.settings/
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# IDE - VSCode
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all"
|
||||||
|
}
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Asanmarket
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
const mongoose = require("mongoose");
|
|
||||||
const db = async () => {
|
|
||||||
try {
|
|
||||||
const connect = await mongoose.connect(process.env.CONNECTION_STRING);
|
|
||||||
console.log(
|
|
||||||
"Database connected: ",
|
|
||||||
connect.connection.host,
|
|
||||||
connect.connection.name
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
setTimeout(() => {
|
|
||||||
console.log("Retry for DB");
|
|
||||||
db();
|
|
||||||
}, 5000);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = db;
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
const nodemailer = require("nodemailer");
|
|
||||||
|
|
||||||
const transporter = nodemailer.createTransport({
|
|
||||||
host: process.env.EMAIL_HOST,
|
|
||||||
port: process.env.EMAIL_PORT,
|
|
||||||
secure: true,
|
|
||||||
auth: {
|
|
||||||
user: process.env.EMAIL_USER,
|
|
||||||
pass: process.env.EMAIL_PASS,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const email = async (to, subject, text, html) => {
|
|
||||||
|
|
||||||
const info = await transporter.sendMail({
|
|
||||||
from: `"Asan Market" ${process.env.EMAIL_ADDRESS}`, // sender address
|
|
||||||
to: to, // list of receivers
|
|
||||||
subject: subject, // Subject line
|
|
||||||
text: text, // plain text body
|
|
||||||
html: html, // html body
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
module.exports = email;
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
|
|
||||||
const axios = require('axios')
|
|
||||||
|
|
||||||
const accountInfo = {
|
|
||||||
Username: '000',
|
|
||||||
Password: '000',
|
|
||||||
Number: '000',
|
|
||||||
url: 'http://www.afe.ir/WebService/V4/BoxService.asmx'
|
|
||||||
}
|
|
||||||
|
|
||||||
/////// http post soap method
|
|
||||||
module.exports.sms = (mobileNumbersArray, message) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
function renderMobileNumbers(array) {
|
|
||||||
if (Array.isArray(array)) {
|
|
||||||
return array.map(item => `<string>${item}</string>`).join('')
|
|
||||||
} else {
|
|
||||||
return `<string>${array}</string>`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const xml = `<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
|
||||||
<soap:Body>
|
|
||||||
<SendMessage xmlns="http://www.afe.ir/">
|
|
||||||
<Username>${accountInfo.Username}</Username>
|
|
||||||
<Password>${accountInfo.Password}</Password>
|
|
||||||
<Number>${accountInfo.Number}</Number>
|
|
||||||
<Mobile>
|
|
||||||
${renderMobileNumbers(mobileNumbersArray)}
|
|
||||||
</Mobile>
|
|
||||||
<Message>${message}</Message>
|
|
||||||
<Type>1</Type>
|
|
||||||
</SendMessage>
|
|
||||||
</soap:Body>
|
|
||||||
</soap:Envelope>`
|
|
||||||
|
|
||||||
axios
|
|
||||||
.post(accountInfo.url, xml, {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'text/xml; charset=utf-8',
|
|
||||||
SOAPAction: 'http://www.afe.ir/SendMessage'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(res => {
|
|
||||||
resolve(res)
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log(
|
|
||||||
'this is sms module error ------------------ status code: %s error message: %s ',
|
|
||||||
err.response.status,
|
|
||||||
err.response.data
|
|
||||||
)
|
|
||||||
resolve(err)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
exports.constants = {
|
|
||||||
VALIDATION_ERROR: 400,
|
|
||||||
UNAUTHORIZED: 401,
|
|
||||||
FORBIDOEN: 403,
|
|
||||||
NOT_FOUND: 404,
|
|
||||||
SERVER_ERROR: 500,
|
|
||||||
SITE_UNAUTHORIZED: 422,
|
|
||||||
TOO_MANY: 429,
|
|
||||||
};
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
const asyncHandler = require("express-async-handler");
|
|
||||||
const News = require("../models/newsModels");
|
|
||||||
const { email } = require("../config/emailConnection");
|
|
||||||
const { checkValidations } = require("../plugins/HelperFunctions")
|
|
||||||
const { body, validationResult } = require('express-validator')
|
|
||||||
const { _sr } = require("../plugins/resServer")
|
|
||||||
const { rateLimit } = require('express-rate-limit')
|
|
||||||
|
|
||||||
const limiter = rateLimit({
|
|
||||||
windowMs: 24 * 60 * 60 * 1000, // 1 minutes
|
|
||||||
limit: 1, // Limit each IP to 100 requests per `window` (here, per 15 minutes).
|
|
||||||
standardHeaders: 'draft-7', // draft-6: `RateLimit-*` headers; draft-7: combined `RateLimit` header
|
|
||||||
legacyHeaders: false, // Disable the `X-RateLimit-*` headers.
|
|
||||||
message: { msg: "Too many requests, please try again later." }
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
*@desc Add new email
|
|
||||||
*@route POST /api/news/
|
|
||||||
*@access private
|
|
||||||
*/
|
|
||||||
const addEmail = [
|
|
||||||
[
|
|
||||||
body('email').notEmpty().isEmail().withMessage(_sr.fa.required.email),
|
|
||||||
],
|
|
||||||
checkValidations(validationResult),
|
|
||||||
limiter,
|
|
||||||
asyncHandler(async (req, res) => {
|
|
||||||
const { email } = req.body
|
|
||||||
const alreadyEmail = await News.findOne({ email })
|
|
||||||
if (alreadyEmail) {
|
|
||||||
res.status(400);
|
|
||||||
throw new Error(_sr.fa.duplicated.email);
|
|
||||||
}
|
|
||||||
const emailAdded = await News.create({
|
|
||||||
email
|
|
||||||
})
|
|
||||||
res.status(200).json(emailAdded)
|
|
||||||
})
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
baseRoute: "/news",
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
off: false,
|
|
||||||
route: "/",
|
|
||||||
method: "post",
|
|
||||||
middleware: [],
|
|
||||||
use: addEmail
|
|
||||||
},
|
|
||||||
|
|
||||||
]
|
|
||||||
};
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
const asyncHandler = require("express-async-handler");
|
|
||||||
const Site = require("../models/siteModels");
|
|
||||||
const { _sr } = require("../plugins/resServer")
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*@desc Get all site
|
|
||||||
*@route GET /api/sites/
|
|
||||||
*@access Public
|
|
||||||
*/
|
|
||||||
const getSite = asyncHandler(async (req, res) => {
|
|
||||||
const profile = await Site.findOne({ profile: "main" });
|
|
||||||
res.status(200).json(profile);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*@desc Update a site
|
|
||||||
*@route PUT /api/sites/
|
|
||||||
*@access private
|
|
||||||
*/
|
|
||||||
const updateSite = [
|
|
||||||
asyncHandler(async (req, res) => {
|
|
||||||
const site = await Site.findOneAndUpdate(
|
|
||||||
{ profile: "main" },
|
|
||||||
req.body,
|
|
||||||
{ new: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!site) {
|
|
||||||
res.status(404);
|
|
||||||
throw new Error(_sr.fa.not_found.item_id);
|
|
||||||
}
|
|
||||||
res.status(200).json(site);
|
|
||||||
})
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
baseRoute: "/sites",
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
off: false,
|
|
||||||
route: "/",
|
|
||||||
method: "get",
|
|
||||||
middleware: ['validateAdminToken', 'hasPermission'],
|
|
||||||
permission: "SITE",
|
|
||||||
use: getSite
|
|
||||||
},
|
|
||||||
{
|
|
||||||
off: false,
|
|
||||||
route: "/id/:id",
|
|
||||||
method: "put",
|
|
||||||
middleware: ['validateAdminToken', 'hasPermission'],
|
|
||||||
permission: "SITE",
|
|
||||||
use: updateSite
|
|
||||||
},
|
|
||||||
]
|
|
||||||
};
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"baseUrl": ".",
|
|
||||||
"paths": {
|
|
||||||
"~/*": ["./*"],
|
|
||||||
"@/*": ["./*"],
|
|
||||||
"~~/*": ["./*"],
|
|
||||||
"@@/*": ["./*"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-13
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"app":"api-delearn",
|
|
||||||
"port":"6060",
|
|
||||||
"disks":[
|
|
||||||
{
|
|
||||||
"name": "uploads",
|
|
||||||
"mountTo": "uploads"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"node": {
|
|
||||||
"version": "18"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
const asyncHandler = require("express-async-handler");
|
|
||||||
const jwt = require("jsonwebtoken");
|
|
||||||
const User = require("../models/userModels");
|
|
||||||
|
|
||||||
const validateToken = asyncHandler(async (req, res, next) => {
|
|
||||||
let token = req.headers.authorization || req.headers.Authorization;
|
|
||||||
|
|
||||||
if (!token) {
|
|
||||||
res.status(401);
|
|
||||||
throw new Error("User is not authorized(N)");
|
|
||||||
} else {
|
|
||||||
const tokenA = await User.findOne({ token })
|
|
||||||
if (tokenA) {
|
|
||||||
jwt.verify(token, process.env.ACCESS_TOKEN_SECERT, (err, decoded) => {
|
|
||||||
if (err) {
|
|
||||||
res.status(401);
|
|
||||||
throw new Error("User is not authorized(JWT E)");
|
|
||||||
}
|
|
||||||
req.user = decoded.user;
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
res.status(401);
|
|
||||||
throw new Error("User is not authorized(DB N)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
module.exports = { name: "validateToken", run: validateToken };
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
const { constants } = require("../constants");
|
|
||||||
const errorHandler = (err, req, res, next) => {
|
|
||||||
const statusCode = res.statusCode ? res.statusCode : 500;
|
|
||||||
|
|
||||||
switch (statusCode) {
|
|
||||||
case constants.VALIDATION_ERROR:
|
|
||||||
res.status(statusCode).json({
|
|
||||||
title: "Validation Failed ",
|
|
||||||
msg: err.message,
|
|
||||||
stackTrace: err.stack,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case constants.NOT_FOUND:
|
|
||||||
res.status(statusCode).json({
|
|
||||||
title: "Not found ",
|
|
||||||
msg: err.message,
|
|
||||||
stackTrace: err.stack,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case constants.FORBIDOEN:
|
|
||||||
res.status(statusCode).json({
|
|
||||||
title: "Forbidoen ",
|
|
||||||
msg: err.message,
|
|
||||||
stackTrace: err.stack,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case constants.SERVER_ERROR:
|
|
||||||
res.status(statusCode).json({
|
|
||||||
title: "Server Error ",
|
|
||||||
msg: err.message,
|
|
||||||
stackTrace: err.stack,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case constants.UNAUTHORIZED:
|
|
||||||
res.status(statusCode).json({
|
|
||||||
title: "Unauthorized ",
|
|
||||||
msg: err.message,
|
|
||||||
stackTrace: err.stack,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case constants.SITE_UNAUTHORIZED:
|
|
||||||
res.status(statusCode).json({
|
|
||||||
title: "Site Unauthorized ",
|
|
||||||
msg: err.message,
|
|
||||||
stackTrace: err.stack,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case constants.TOO_MANY:
|
|
||||||
res.status(statusCode).json({
|
|
||||||
title: "Too many request",
|
|
||||||
msg: err.message,
|
|
||||||
stackTrace: err.stack,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.log(err);
|
|
||||||
res.status(500).json({ err: err.message, msg: "Unhandled error" })
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = { name: "errorHandler", run: errorHandler };
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
const asyncHandler = require("express-async-handler");
|
|
||||||
const User = require("../models/userModels");
|
|
||||||
|
|
||||||
const hasPerma = (perm) => {
|
|
||||||
return asyncHandler(async (req, res, next) => {
|
|
||||||
const user = await User.findId(req.user.id)
|
|
||||||
if (user && (user.permissions.includes(perm) || !user.permissions.includes("ADMIN"))) {
|
|
||||||
return next()
|
|
||||||
} else {
|
|
||||||
res.status(401); throw new Error('کاربر مجوز لازم را ندارد');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { name: "hasPermission", run: hasPerma };
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
const asyncHandler = require("express-async-handler");
|
|
||||||
const jwt = require("jsonwebtoken");
|
|
||||||
const Admin = require("../models/adminModels");
|
|
||||||
const validateAdminToken = asyncHandler(async (req, res, next) => {
|
|
||||||
let token = req.headers.siteuser || req.headers.SiteUser;
|
|
||||||
|
|
||||||
if (!token) {
|
|
||||||
res.status(401);
|
|
||||||
throw new Error("User is not authorized(N)");
|
|
||||||
} else {
|
|
||||||
const tokenA = await Admin.findOne({ token })
|
|
||||||
if (tokenA) {
|
|
||||||
jwt.verify(token, process.env.ACCESS_TOKEN_SECERT_ADMIN, (err, decoded) => {
|
|
||||||
if (err) {
|
|
||||||
res.status(401);
|
|
||||||
throw new Error("User is not authorized(JWT E)");
|
|
||||||
}
|
|
||||||
req.admin = decoded.user;
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
res.status(401);
|
|
||||||
throw new Error("User is not authorized(DB N)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
module.exports = { name: "validateAdminToken", run: validateAdminToken };
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
const asyncHandler = require("express-async-handler");
|
|
||||||
const jwt = require("jsonwebtoken");
|
|
||||||
const User = require("../models/userModels");
|
|
||||||
|
|
||||||
const validateToken = asyncHandler(async (req, res, next) => {
|
|
||||||
let token = req.headers.authorization || req.headers.Authorization;
|
|
||||||
|
|
||||||
if (!token) {
|
|
||||||
res.status(401);
|
|
||||||
throw new Error("User is not authorized(N)");
|
|
||||||
} else {
|
|
||||||
const tokenA = await User.findOne({ token })
|
|
||||||
if (tokenA) {
|
|
||||||
jwt.verify(token, process.env.ACCESS_TOKEN_SECERT, (err, decoded) => {
|
|
||||||
if (err) {
|
|
||||||
res.status(401);
|
|
||||||
throw new Error("User is not authorized(JWT E)");
|
|
||||||
}
|
|
||||||
req.user = decoded.user;
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
res.status(401);
|
|
||||||
throw new Error("User is not authorized(DB N)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
module.exports = { name: "validateToken", run: validateToken };
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
const mongoose = require("mongoose");
|
|
||||||
|
|
||||||
const newsSchema = new mongoose.Schema({
|
|
||||||
email: {
|
|
||||||
type: String,
|
|
||||||
unique: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamps: true,
|
|
||||||
versionKey: false
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
module.exports = mongoose.model("News", newsSchema);
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
const mongoose = require("mongoose");
|
|
||||||
|
|
||||||
const siteSchema = new mongoose.Schema(
|
|
||||||
{
|
|
||||||
profile: {
|
|
||||||
type: String,
|
|
||||||
default: "main",
|
|
||||||
unique: true
|
|
||||||
},
|
|
||||||
name: {
|
|
||||||
type: String,
|
|
||||||
default: "Dlearn",
|
|
||||||
},
|
|
||||||
desc: {
|
|
||||||
type: String,
|
|
||||||
default: "Dlearn, marketplace core by Swift",
|
|
||||||
},
|
|
||||||
logo: {
|
|
||||||
type: String,
|
|
||||||
default: "/upload/Default.png",
|
|
||||||
},
|
|
||||||
tel1: {
|
|
||||||
type: String,
|
|
||||||
default: "+989391885657",
|
|
||||||
},
|
|
||||||
tel2: {
|
|
||||||
type: String,
|
|
||||||
default: "+989391885657",
|
|
||||||
},
|
|
||||||
address: {
|
|
||||||
type: String,
|
|
||||||
default: "Iran, Markazi",
|
|
||||||
},
|
|
||||||
socialMedia: [
|
|
||||||
{
|
|
||||||
kind: String,
|
|
||||||
address: String
|
|
||||||
}
|
|
||||||
],
|
|
||||||
emailHost: String,
|
|
||||||
emailPort: String,
|
|
||||||
emailUser: String,
|
|
||||||
emailPass: String,
|
|
||||||
smsNumber: String,
|
|
||||||
smsUser: String,
|
|
||||||
smsPass: String,
|
|
||||||
underConstruction: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamps: true,
|
|
||||||
versionKey: false
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
module.exports = mongoose.model("Site", siteSchema);
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"collection": "@nestjs/schematics",
|
||||||
|
"sourceRoot": "src"
|
||||||
|
}
|
||||||
Generated
-4648
File diff suppressed because it is too large
Load Diff
+109
-26
@@ -1,34 +1,117 @@
|
|||||||
{
|
{
|
||||||
"name": "asanmarket",
|
"name": "DLearn",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"private": true,
|
||||||
|
"license": "UNLICENSED",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node server.js",
|
"prebuild": "rimraf dist",
|
||||||
"dev": "nodemon server.js"
|
"build": "nest build",
|
||||||
|
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
||||||
|
"start": "nest start",
|
||||||
|
"start:dev": "nest start --watch",
|
||||||
|
"start:debug": "nest start --debug --watch",
|
||||||
|
"start:prod": "node dist/main",
|
||||||
|
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
|
||||||
|
"test": "jest",
|
||||||
|
"test:watch": "jest --watch",
|
||||||
|
"test:cov": "jest --coverage",
|
||||||
|
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
||||||
|
"test:e2e": "jest --config ./test/jest-e2e.json"
|
||||||
},
|
},
|
||||||
"author": "swift",
|
"author": "daniel.3380",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.6.2",
|
"@nestjs/axios": "^2.0.0",
|
||||||
"bcrypt": "^5.1.0",
|
"@nestjs/common": "^10.0.5",
|
||||||
"cors": "^2.8.5",
|
"@nestjs/core": "^10.0.5",
|
||||||
"cron": "^3.1.6",
|
"@nestjs/mongoose": "^10.0.6",
|
||||||
"dotenv": "^16.3.1",
|
"@nestjs/platform-express": "^10.0.5",
|
||||||
"express": "^4.18.2",
|
"@nestjs/platform-socket.io": "^10.0.5",
|
||||||
"express-async-handler": "^1.2.0",
|
"@nestjs/serve-static": "^4.0.0",
|
||||||
"express-fileupload": "^1.4.1",
|
"@nestjs/swagger": "^7.1.1",
|
||||||
"express-rate-limit": "^7.2.0",
|
"@nestjs/testing": "^9.4.0",
|
||||||
"express-route-detector": "^1.1.0",
|
"@nestjs/throttler": "^4.0.0",
|
||||||
"express-sharp": "^4.2.41",
|
"@types/axios": "^0.14.0",
|
||||||
"express-validator": "^7.0.1",
|
"@types/crypto-js": "^4.1.1",
|
||||||
"jsonwebtoken": "^9.0.0",
|
"@types/express-session": "1.17.0",
|
||||||
"moment": "^2.29.4",
|
"@types/moment": "^2.13.0",
|
||||||
"mongodb": "^5.6.0",
|
"@types/multer": "^1.4.7",
|
||||||
"mongoose": "^7.3.1",
|
"@types/request": "^2.48.8",
|
||||||
"mongoose-sequence": "^6.0.1",
|
"@types/request-ip": "^0.0.37",
|
||||||
"nodemailer": "^6.9.4",
|
"axios": "^1.3.6",
|
||||||
"nodemon": "^2.0.22",
|
"base64-async": "^2.1.3",
|
||||||
"swiftly-tools": "1.2.82"
|
"bluebird": "^3.7.2",
|
||||||
|
"class-transformer": "^0.5.1",
|
||||||
|
"class-validator": "^0.14.0",
|
||||||
|
"cookie-parser": "^1.4.6",
|
||||||
|
"crypto-js": "^4.1.1",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
|
"ejs": "^3.1.8",
|
||||||
|
"express-session": "^1.17.2",
|
||||||
|
"fs": "^0.0.1-security",
|
||||||
|
"jalali-moment": "^3.3.11",
|
||||||
|
"jsonwebtoken": "^8.5.1",
|
||||||
|
"md5": "^2.3.0",
|
||||||
|
"mongoose": "^8.3.2",
|
||||||
|
"mysql": "^2.18.1",
|
||||||
|
"mysql2": "^3.2.3",
|
||||||
|
"path": "^0.12.7",
|
||||||
|
"pg": "^8.11.1",
|
||||||
|
"pm2": "^5.2.0",
|
||||||
|
"qrcode": "^1.5.0",
|
||||||
|
"random-number": "^0.0.9",
|
||||||
|
"reflect-metadata": "^0.1.13",
|
||||||
|
"request": "^2.88.2",
|
||||||
|
"request-ip": "^2.1.3",
|
||||||
|
"rimraf": "^3.0.2",
|
||||||
|
"rxjs": "^7.5.5",
|
||||||
|
"sequelize": "^6.32.1",
|
||||||
|
"sequelize-typescript": "^2.1.5",
|
||||||
|
"shelljs": "^0.8.5",
|
||||||
|
"soap": "^1.0.0",
|
||||||
|
"swagger-ui-express": "^4.6.3",
|
||||||
|
"ts-loader": "^9.4.2",
|
||||||
|
"typescript": "^5.1.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@nestjs/cli": "^8.2.5",
|
||||||
|
"@nestjs/schematics": "^8.0.11",
|
||||||
|
"@types/bluebird": "^3.5.36",
|
||||||
|
"@types/express": "^4.17.13",
|
||||||
|
"@types/jest": "27.0.2",
|
||||||
|
"@types/jsonwebtoken": "^8.5.8",
|
||||||
|
"@types/md5": "^2.3.2",
|
||||||
|
"@types/node": "^16.11.33",
|
||||||
|
"@types/qrcode": "^1.4.2",
|
||||||
|
"@types/supertest": "^2.0.12",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.22.0",
|
||||||
|
"@typescript-eslint/parser": "^5.22.0",
|
||||||
|
"eslint": "^8.15.0",
|
||||||
|
"eslint-config-prettier": "^8.5.0",
|
||||||
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
|
"jest": "^27.5.1",
|
||||||
|
"prettier": "^2.6.2",
|
||||||
|
"source-map-support": "^0.5.20",
|
||||||
|
"supertest": "^6.2.3",
|
||||||
|
"ts-jest": "^27.1.4",
|
||||||
|
"ts-node": "^10.7.0",
|
||||||
|
"tsconfig-paths": "^3.14.1"
|
||||||
|
},
|
||||||
|
"jest": {
|
||||||
|
"moduleFileExtensions": [
|
||||||
|
"js",
|
||||||
|
"json",
|
||||||
|
"ts"
|
||||||
|
],
|
||||||
|
"rootDir": "src",
|
||||||
|
"testRegex": ".*\\.spec\\.ts$",
|
||||||
|
"transform": {
|
||||||
|
"^.+\\.(t|j)s$": "ts-jest"
|
||||||
|
},
|
||||||
|
"collectCoverageFrom": [
|
||||||
|
"**/*.(t|j)s"
|
||||||
|
],
|
||||||
|
"coverageDirectory": "../coverage",
|
||||||
|
"testEnvironment": "node"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
populate: {
|
|
||||||
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,195 +0,0 @@
|
|||||||
const fs = require("fs");
|
|
||||||
const path = require("path");
|
|
||||||
const moment = require("moment");
|
|
||||||
const date = moment();
|
|
||||||
|
|
||||||
const uploadImage = (image, res, type) => {
|
|
||||||
const maxSize = 15 * 1024 * 1024; // 15MB (example limit)
|
|
||||||
|
|
||||||
if (image.size > maxSize) {
|
|
||||||
res.status(500)
|
|
||||||
throw new Error("Image file size exceeds the limit")
|
|
||||||
}
|
|
||||||
let imageName =
|
|
||||||
date.format("YYYY-MM-DD") +
|
|
||||||
"-Img-" +
|
|
||||||
Math.floor(Math.random() * 900) +
|
|
||||||
100 +
|
|
||||||
image.name;
|
|
||||||
|
|
||||||
let saveToPath
|
|
||||||
let preFile
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case "1":
|
|
||||||
// Specify the save location
|
|
||||||
saveToPath = path.join(__dirname, "..", "uploads/products", imageName);
|
|
||||||
preFile = "/uploads/products/"
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "2":
|
|
||||||
// Specify the save location
|
|
||||||
saveToPath = path.join(__dirname, "..", "uploads/blogs", imageName);
|
|
||||||
preFile = "/uploads/blogs/"
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "3":
|
|
||||||
// Specify the save location
|
|
||||||
saveToPath = path.join(__dirname, "..", "uploads/personal", imageName);
|
|
||||||
preFile = "/uploads/personal/"
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// Specify the save location
|
|
||||||
saveToPath = path.join(__dirname, "..", "uploads/none", imageName);
|
|
||||||
preFile = "/uploads/none/"
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.writeFile(saveToPath, image.data, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error(err);
|
|
||||||
res.status(500).json({ msg: "Error saving the image" });
|
|
||||||
} else {
|
|
||||||
res.status(201).json({ url: `${preFile}${imageName}` });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const uploadImages = (images, res, type) => {
|
|
||||||
const maxSize = 15 * 1024 * 1024; // 15MB (example limit)
|
|
||||||
const imageUrls = [];
|
|
||||||
|
|
||||||
if (!Array.isArray(images)) {
|
|
||||||
|
|
||||||
if (images.size > maxSize) {
|
|
||||||
res.status(500)
|
|
||||||
throw new Error("Image file size exceeds the limit")
|
|
||||||
}
|
|
||||||
|
|
||||||
let imageName =
|
|
||||||
date.format("YYYY-MM-DD") +
|
|
||||||
"-Img-" +
|
|
||||||
Math.floor(Math.random() * 900) +
|
|
||||||
100 +
|
|
||||||
images.name;
|
|
||||||
|
|
||||||
let saveToPath
|
|
||||||
let preFile
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case "1":
|
|
||||||
// Specify the save location
|
|
||||||
saveToPath = path.join(__dirname, "..", "uploads/products", imageName);
|
|
||||||
preFile = "/uploads/products/"
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "2":
|
|
||||||
// Specify the save location
|
|
||||||
saveToPath = path.join(__dirname, "..", "uploads/blogs", imageName);
|
|
||||||
preFile = "/uploads/blogs/"
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "3":
|
|
||||||
// Specify the save location
|
|
||||||
saveToPath = path.join(__dirname, "..", "uploads/personal", imageName);
|
|
||||||
preFile = "/uploads/personal/"
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// Specify the save location
|
|
||||||
saveToPath = path.join(__dirname, "..", "uploads/none", imageName);
|
|
||||||
preFile = "/uploads/none/"
|
|
||||||
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.writeFile(saveToPath, images.data, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error(err);
|
|
||||||
res.status(500).json({ msg: "Error saving the image" });
|
|
||||||
} else {
|
|
||||||
imageUrls.push(`${preFile}${imageName}`)
|
|
||||||
res.status(201).json({ urls: imageUrls });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
images.forEach(async (image) => {
|
|
||||||
if (image.size > maxSize) {
|
|
||||||
res.status(400)
|
|
||||||
throw new Error("Image file size exceeds the limit")
|
|
||||||
}
|
|
||||||
|
|
||||||
let imageName =
|
|
||||||
date.format("YYYY-MM-DD") +
|
|
||||||
"-Img-" +
|
|
||||||
Math.floor(Math.random() * 900) +
|
|
||||||
100 +
|
|
||||||
image.name;
|
|
||||||
|
|
||||||
let saveToPath
|
|
||||||
let preFile
|
|
||||||
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case "1":
|
|
||||||
// Specify the save location
|
|
||||||
saveToPath = path.join(__dirname, "..", "uploads/products", imageName);
|
|
||||||
preFile = "/uploads/products/"
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "2":
|
|
||||||
// Specify the save location
|
|
||||||
saveToPath = path.join(__dirname, "..", "uploads/blogs", imageName);
|
|
||||||
preFile = "/uploads/blogs/"
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "3":
|
|
||||||
// Specify the save location
|
|
||||||
saveToPath = path.join(__dirname, "..", "uploads/personal", imageName);
|
|
||||||
preFile = "/uploads/personal/"
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// Specify the save location
|
|
||||||
saveToPath = path.join(__dirname, "..", "uploads/none", imageName);
|
|
||||||
preFile = "/uploads/none/"
|
|
||||||
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
imageUrls.push(`${preFile}${imageName}`);
|
|
||||||
|
|
||||||
fs.writeFile(saveToPath, image.data, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.log(err);
|
|
||||||
res.status(500)
|
|
||||||
throw new Error("Can't save images")
|
|
||||||
okd = false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
res.status(201).json({ urls: imageUrls });
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
const deleteImage = (address, res) => {
|
|
||||||
const addressOf = path.join(__dirname, "..", address);
|
|
||||||
|
|
||||||
fs.unlink(addressOf, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error("Error removing image:", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
deleteImage,
|
|
||||||
uploadImage,
|
|
||||||
uploadImages,
|
|
||||||
};
|
|
||||||
@@ -1,314 +0,0 @@
|
|||||||
module.exports._sr = {
|
|
||||||
fa: {
|
|
||||||
required: {
|
|
||||||
token: 'توکن را وارد کنید',
|
|
||||||
field: 'این فیلد نباید خالی باشد',
|
|
||||||
// developer validations
|
|
||||||
remember_me: 'پارامتر remember_me الزامی است',
|
|
||||||
// registration validations
|
|
||||||
name: 'نام را وارد کنید',
|
|
||||||
first_name: 'نام را وارد کنید',
|
|
||||||
last_name: 'نام خانوادگی را وارد کنید',
|
|
||||||
email: 'ایمیل را وارد کنید',
|
|
||||||
national_code: 'کد ملی الزامی است',
|
|
||||||
email_personal: 'ایمیل شخصی الزامی است',
|
|
||||||
email_company: 'ایمیل کمپانی برای اشخاص حقوقی الزامی است',
|
|
||||||
company_name: 'درصورتی که شخص حقوقی هستید، نام کمپانی را وارد کنید',
|
|
||||||
username: 'نام کاربری را وارد کنید',
|
|
||||||
phone_number: 'شماره تماس را وارد کنید',
|
|
||||||
gender: "جنسیت خود را انتخاب کنید",
|
|
||||||
password: 'پسورد را وارد کنید',
|
|
||||||
birthdate: 'تاریخ تولد را وارد کنید',
|
|
||||||
permissions: 'مقدار دسترسی را وارد کنید',
|
|
||||||
// addressing validations
|
|
||||||
country: 'کشور را وارد کنید',
|
|
||||||
province: 'استان را وارد کنید',
|
|
||||||
city: 'شهر را وارد کنید',
|
|
||||||
address: 'آدرس را وارد کنید',
|
|
||||||
postal_code: 'کد پستی را وارد کنید',
|
|
||||||
plaque: 'پلاک را وارد کنید',
|
|
||||||
receiver_first_name: 'نام گیرنده را وارد کنید',
|
|
||||||
receiver_last_name: 'نام خانوادگی گیرنده را وارد کنید',
|
|
||||||
receiver_mobile: 'شماره موبایل گیرنده را وارد کنید',
|
|
||||||
// global (post - gallery - ...)
|
|
||||||
title: 'عنوان را وارد کنید',
|
|
||||||
caption: 'متن را وارد کنید',
|
|
||||||
description: 'توضیحات را وارد کنید',
|
|
||||||
category: 'دسته بندی را انتخاب کنید',
|
|
||||||
image: 'عکس اجباری است',
|
|
||||||
cover: 'کاور اجباری است',
|
|
||||||
file: 'فایل اجباری است',
|
|
||||||
message: 'پیام را بنویسید',
|
|
||||||
quantity: 'تعداد را وارد کنید',
|
|
||||||
date: 'تاریخ را وارد کنید',
|
|
||||||
reason: 'دلیل را انتخاب کنید',
|
|
||||||
question: 'سوال را بنویسید',
|
|
||||||
answer: 'جواب را بنویسید',
|
|
||||||
price: 'قیمت را وارد کنید',
|
|
||||||
type: 'نوع را انتخاب کنید',
|
|
||||||
discount_code: 'کد تخفیف را وارد کنید',
|
|
||||||
discount_amount: 'مقدار تخفیف را وارد کنید',
|
|
||||||
discount_expire_date: 'تاریخ انقضای کد تخفیف را مشخص کنید',
|
|
||||||
user_id: 'کاربر را انتخاب کنید',
|
|
||||||
video: 'ویدیو اجباری است',
|
|
||||||
setting_name: 'نام تنظیمات اجباری است',
|
|
||||||
setting_value: 'مقدار تنظیمات اجباری است'
|
|
||||||
},
|
|
||||||
format: {
|
|
||||||
phone_number: 'فرمت شماره تماس صحیح نیست',
|
|
||||||
email: 'فرمت ایمیل قابل قبول نیست',
|
|
||||||
number: 'مقدار باید از جنس عدد باشد',
|
|
||||||
boolean: 'مقدار باید از جنس Boolean باشد',
|
|
||||||
image: 'فرمت عکس قابل قبول نیست',
|
|
||||||
video: 'فرمت ویدیو قابل قبول نیست',
|
|
||||||
national_code: 'کد ملی صحیح نیست'
|
|
||||||
},
|
|
||||||
min_char: {
|
|
||||||
min2: 'حداقل 2 کاراکتر',
|
|
||||||
min4: 'حداقل 4 کاراکتر',
|
|
||||||
min8: 'حداقل 8 کاراکتر',
|
|
||||||
min10: 'حداقل 10 کاراکتر',
|
|
||||||
min20: 'حداقل 20 کاراکتر',
|
|
||||||
min30: 'حداقل 30 کاراکتر',
|
|
||||||
min40: 'حداقل 40 کاراکتر',
|
|
||||||
min50: 'حداقل 50 کاراکتر',
|
|
||||||
min60: 'حداقل 60 کاراکتر',
|
|
||||||
min100: 'حداقل 100 کاراکتر',
|
|
||||||
min120: 'حداقل 120 کاراکتر',
|
|
||||||
min150: 'حداقل 150 کاراکتر',
|
|
||||||
min200: 'حداقل 200 کاراکتر',
|
|
||||||
data_size: 'حجم قابل قبول حداقل: ',
|
|
||||||
image_width_size: 'عرض حداقل: ',
|
|
||||||
image_height_size: 'ارتفاع حداقل: '
|
|
||||||
},
|
|
||||||
max_char: {
|
|
||||||
max4: 'حداکثر 4 کاراکتر',
|
|
||||||
max8: 'حداکثر 8 کاراکتر',
|
|
||||||
max10: 'حداکثر 10 کاراکتر',
|
|
||||||
max15: 'حداکثر 15 کاراکتر',
|
|
||||||
max20: 'حداکثر 20 کاراکتر',
|
|
||||||
max30: 'حداکثر 30 کاراکتر',
|
|
||||||
max40: 'حداکثر 40 کاراکتر',
|
|
||||||
max50: 'حداکثر 50 کاراکتر',
|
|
||||||
max60: 'حداکثر 60 کاراکتر',
|
|
||||||
max100: 'حداکثر 100 کاراکتر',
|
|
||||||
max120: 'حداکثر 120 کاراکتر',
|
|
||||||
max150: 'حداکثر 150 کاراکتر',
|
|
||||||
max200: 'حداکثر 200 کاراکتر',
|
|
||||||
data_size: 'حجم قابل قبول حداکثر: ',
|
|
||||||
image_width_size: 'عرض حداکثر: ',
|
|
||||||
image_height_size: 'ارتفاع حداکثر: '
|
|
||||||
},
|
|
||||||
not_found: {
|
|
||||||
user_id: 'کاربری با این مشخصات وجود ندارد',
|
|
||||||
admin_id: 'ادمینی با این مشخصات وجود ندارد',
|
|
||||||
order_id: 'سفارشی با این مشخصات وجود ندارد',
|
|
||||||
item_id: 'موردی با این مشخصات وجود ندارد',
|
|
||||||
password: 'رمز عبور یا آیدی درست نیست',
|
|
||||||
user_not_exist: 'اطلاعات یوزر موجود نیست'
|
|
||||||
},
|
|
||||||
duplicated: {
|
|
||||||
username: 'این نام کاربری از قبل وجود دارد',
|
|
||||||
email: 'این ایمیل از قبل وجود دارد',
|
|
||||||
name: 'نام تکراری است',
|
|
||||||
title: 'عنوان تکراری است',
|
|
||||||
phone_number: 'این شماره تماس از قبل وجود دارد',
|
|
||||||
link: 'این لینک تکراری است',
|
|
||||||
code: ' این کد تکراری است',
|
|
||||||
item: 'این مورد تگراری است',
|
|
||||||
shop: 'این فروشگاه وجود دارد'
|
|
||||||
},
|
|
||||||
response: {
|
|
||||||
permissions: 'شما مجوز کافی ندارید ',
|
|
||||||
logged_in: 'شما وارد سیستم شدید',
|
|
||||||
not_logged_in: 'شما وارد سیستم نشدید',
|
|
||||||
logged_out: 'شما از سیستم خارج شدید',
|
|
||||||
unauthenticated: 'غیرمجاز',
|
|
||||||
recovery_link: 'لینک بازیابی فرستاده شد',
|
|
||||||
success_save: 'با موفقیت ثبت شد',
|
|
||||||
success_remove: 'با موفقیت حذف شد',
|
|
||||||
cart_empty: 'سبد خرید خالی است',
|
|
||||||
already_has_address: 'آدرس قبلا اضافه شده',
|
|
||||||
activation_code: 'کد فعالسازی برای شما ارسال شد',
|
|
||||||
activation_email: 'ایمیل فعال سازی برای شما ارسال شد',
|
|
||||||
expired_reset_link: 'این لینک بازیابی منقضی شده است',
|
|
||||||
email_not_confirmed: 'ابتدا ایمیل خود را تایید کنید،لینک فعال سازی قبلا برای شما فرستاده شده است.',
|
|
||||||
expired_activation_link: 'این لینک فعال سازی منقضی شده است',
|
|
||||||
success_activation: 'اکانت شما با موفقیت فعال شد',
|
|
||||||
passwords_not_match: 'پسورد ها یکی نیست',
|
|
||||||
problem: 'مشکلی پیش آمده، لطفا دوباره تلاش کنید.',
|
|
||||||
latinChar: 'لطفا با حروف لاتین بنویسید',
|
|
||||||
persianChar: 'لطفا با حروف فارسی بنویسید',
|
|
||||||
whiteSpace: 'بین حروف و کلمات نباید فاصله باشد',
|
|
||||||
wrongLoginEmail: 'ایمیل یا رمز ورود اشتباه است',
|
|
||||||
wrongLoginNumber: 'شماره یا رمز ورود اشتباه است',
|
|
||||||
user_not_valid: 'اطلاعات یوزر معتبر نیست',
|
|
||||||
otp: 'کد اشتباه است'
|
|
||||||
},
|
|
||||||
file_types: {
|
|
||||||
jpg: 'فقط فرمت jpg قابل قبول است',
|
|
||||||
png: 'فقط فرمت png قابل قبول است',
|
|
||||||
gif: 'فقط فرمت gif قابل قبول است',
|
|
||||||
pdf: 'فقط فرمت pdf قابل قبول است',
|
|
||||||
txt: 'فقط فرمت txt قابل قبول است',
|
|
||||||
log: 'فقط فرمت log قابل قبول است',
|
|
||||||
mp3: 'فقط فرمت mp3 قابل قبول است',
|
|
||||||
ogg: 'فقط فرمت ogg قابل قبول است',
|
|
||||||
wmv: 'فقط فرمت wmv قابل قبول است',
|
|
||||||
mp4: 'فقط فرمت mp4 قابل قبول است',
|
|
||||||
mov: 'فقط فرمت mov قابل قبول است',
|
|
||||||
mkv: 'فقط فرمت mkv قابل قبول است',
|
|
||||||
flv: 'فقط فرمت flv قابل قبول است'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
en: {
|
|
||||||
required: {
|
|
||||||
token: 'Token is required',
|
|
||||||
field: 'This field is required',
|
|
||||||
// developer validations
|
|
||||||
remember_me: 'Remember_me parameter required',
|
|
||||||
// registration validations
|
|
||||||
name: 'Enter name',
|
|
||||||
first_name: 'Enter first name',
|
|
||||||
last_name: 'Enter last name',
|
|
||||||
national_code: 'National code is required',
|
|
||||||
email: 'Enter email',
|
|
||||||
email_personal: 'Personal email is required',
|
|
||||||
email_company: 'Company email is required for legal entities',
|
|
||||||
company_name: 'Enter company name if you are a legal entity',
|
|
||||||
username: 'Enter username',
|
|
||||||
phone_number: 'Enter phone number',
|
|
||||||
password: 'Enter password',
|
|
||||||
birthdate: 'Enter birthdate',
|
|
||||||
// addressing validations
|
|
||||||
country: 'Enter country',
|
|
||||||
province: 'Enter province',
|
|
||||||
city: 'Enter city',
|
|
||||||
address: 'Enter address',
|
|
||||||
postal_code: 'Enter postal code',
|
|
||||||
plaque: 'Enter plaque',
|
|
||||||
receiver_first_name: 'Enter recipient name',
|
|
||||||
receiver_last_name: 'Enter recipient surname',
|
|
||||||
receiver_mobile: "Enter recipient's mobile number",
|
|
||||||
// global (post - gallery - ...)
|
|
||||||
title: 'Enter title',
|
|
||||||
caption: 'Enter caption',
|
|
||||||
description: 'Enter description',
|
|
||||||
category: 'Select category',
|
|
||||||
image: 'Image is required',
|
|
||||||
cover: 'Cover is required',
|
|
||||||
file: 'File is required',
|
|
||||||
message: 'Write message',
|
|
||||||
quantity: 'Enter quantity',
|
|
||||||
date: 'Enter date',
|
|
||||||
reason: 'Select reason',
|
|
||||||
question: 'Write the question',
|
|
||||||
answer: 'Write the answer',
|
|
||||||
price: 'Enter Price',
|
|
||||||
type: 'Select type',
|
|
||||||
discount_code: 'Enter discount code',
|
|
||||||
discount_amount: 'Enter discount amount',
|
|
||||||
discount_expire_date: 'Specify discount code expiration date',
|
|
||||||
user_id: 'Select user',
|
|
||||||
video: 'Video is required'
|
|
||||||
},
|
|
||||||
format: {
|
|
||||||
phone_number: 'Phone number format in incorrect',
|
|
||||||
email: 'Email format is not correct',
|
|
||||||
number: 'Value must be number',
|
|
||||||
boolean: 'Value must be Boolean',
|
|
||||||
image: 'Photo format is not acceptable',
|
|
||||||
video: 'Video format is not acceptable',
|
|
||||||
national_code: 'National code format is not correct'
|
|
||||||
},
|
|
||||||
min_char: {
|
|
||||||
min2: 'At least 2 characters',
|
|
||||||
min4: 'At least 4 characters',
|
|
||||||
min8: 'At least 8 characters',
|
|
||||||
min10: 'At least 10 characters',
|
|
||||||
min20: 'At least 20 characters',
|
|
||||||
min30: 'At least 30 characters',
|
|
||||||
min40: 'At least 40 characters',
|
|
||||||
min50: 'At least 50 characters',
|
|
||||||
min60: 'At least 60 characters',
|
|
||||||
min100: 'At least 100 characters',
|
|
||||||
min120: 'At least 120 characters',
|
|
||||||
min150: 'At least 150 characters',
|
|
||||||
min200: 'At least 200 characters',
|
|
||||||
data_size: 'Acceptable minimum size: ',
|
|
||||||
image_width_size: 'Minimum width: ',
|
|
||||||
image_height_size: 'Minimum height: '
|
|
||||||
},
|
|
||||||
max_char: {
|
|
||||||
max4: 'Maximum 4 characters',
|
|
||||||
max8: 'Maximum 8 characters',
|
|
||||||
max10: 'Maximum 10 characters',
|
|
||||||
max15: 'Maximum 15 characters',
|
|
||||||
max20: 'Maximum 20 characters',
|
|
||||||
max30: 'Maximum 30 characters',
|
|
||||||
max40: 'Maximum 40 characters',
|
|
||||||
max50: 'Maximum 50 characters',
|
|
||||||
max60: 'Maximum 60 characters',
|
|
||||||
max100: 'Maximum 100 characters',
|
|
||||||
max120: 'Maximum 120 characters',
|
|
||||||
max150: 'Maximum 150 characters',
|
|
||||||
max200: 'Maximum 200 characters',
|
|
||||||
data_size: 'Maximum acceptable size: ',
|
|
||||||
image_width_size: 'Maximum width: ',
|
|
||||||
image_height_size: 'Maximum height: '
|
|
||||||
},
|
|
||||||
not_found: {
|
|
||||||
user_id: 'There is no user with this profile',
|
|
||||||
admin_id: 'There is no admin with this profile',
|
|
||||||
order_id: 'There is no order with this profile',
|
|
||||||
item_id: 'There is no item with this specification',
|
|
||||||
password: 'Password or ID is incorrect'
|
|
||||||
},
|
|
||||||
duplicated: {
|
|
||||||
username: 'This username already exists',
|
|
||||||
email: 'This email already exists',
|
|
||||||
name: 'Name already exists',
|
|
||||||
title: 'Title already exists',
|
|
||||||
phone_number: 'Phone number already exists'
|
|
||||||
},
|
|
||||||
response: {
|
|
||||||
logged_in: 'You are logged in',
|
|
||||||
not_logged_in: 'You are not logged in',
|
|
||||||
logged_out: 'You are logged out',
|
|
||||||
unauthenticated: 'unauthenticated',
|
|
||||||
recovery_link: 'Recovery link sent',
|
|
||||||
success_save: 'Successfully saved',
|
|
||||||
success_remove: 'Successfully removed',
|
|
||||||
cart_empty: 'Cart is empty',
|
|
||||||
already_has_address: 'Already has address',
|
|
||||||
activation_code: 'Activation code sent to you',
|
|
||||||
activation_email: 'Activation email sent to you',
|
|
||||||
expired_reset_link: 'The current reset pass link has been expired',
|
|
||||||
email_not_confirmed: 'Confirm your email first, the activation link has already been sent to you.',
|
|
||||||
expired_activation_link: 'This activation link has expired',
|
|
||||||
success_activation: 'Your account has been successfully activated',
|
|
||||||
passwords_not_match: 'Passwords are not the same',
|
|
||||||
problem: 'There is a problem, please try again.',
|
|
||||||
latinChar: 'Please write in Latin letters',
|
|
||||||
persianChar: 'Please write in Persian letters',
|
|
||||||
whiteSpace: 'There should be no space between letters and words'
|
|
||||||
},
|
|
||||||
file_types: {
|
|
||||||
jpg: 'Only jpg format is acceptable',
|
|
||||||
png: 'Only png format is acceptable',
|
|
||||||
gif: 'Only gif format is acceptable',
|
|
||||||
pdf: 'Only pdf format is acceptable',
|
|
||||||
txt: 'Only txt format is acceptable',
|
|
||||||
log: 'Only log format is acceptable',
|
|
||||||
mp3: 'Only mp3 format is acceptable',
|
|
||||||
ogg: 'Only ogg format is acceptable',
|
|
||||||
wmv: 'Only wmv format is acceptable',
|
|
||||||
mp4: 'Only mp4 format is acceptable',
|
|
||||||
mov: 'Only mov format is acceptable',
|
|
||||||
mkv: 'Only mkv format is acceptable',
|
|
||||||
flv: 'Only flv format is acceptable'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
supportedImageFormats: ['jpg', 'jpeg', 'png', 'svg', 'svg+xml', 'webp'],
|
|
||||||
supportedVideoFormats: ['mp4', 'wmv']
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
const express = require("express");
|
|
||||||
const errorHandler = require("./middleware/errorHandler");
|
|
||||||
const videovalidate = require("./middleware/vidoeValidate");
|
|
||||||
const db = require("./config/dbConnectoin");
|
|
||||||
const fileUpload = require("express-fileupload");
|
|
||||||
const path = require("path");
|
|
||||||
const swiftly = require("swiftly-tools");
|
|
||||||
const { expressSharp, FsAdapter } = require('express-sharp')
|
|
||||||
const { autoFetch } = require('express-route-detector')
|
|
||||||
var cors = require('cors')
|
|
||||||
require("dotenv").config();
|
|
||||||
|
|
||||||
// Init database
|
|
||||||
db();
|
|
||||||
|
|
||||||
const app = express();
|
|
||||||
const port = process.env.PORT || 6060;
|
|
||||||
|
|
||||||
// Middleware
|
|
||||||
app.use(cors())
|
|
||||||
app.use(fileUpload());
|
|
||||||
app.use(express.json());
|
|
||||||
app.use(express.urlencoded({ extended: false }));
|
|
||||||
app.use(swiftly.middleware.hsts)
|
|
||||||
app.use(swiftly.middleware.sign("Mr Swift"))
|
|
||||||
|
|
||||||
// Routes
|
|
||||||
app.use(autoFetch(express))
|
|
||||||
app.use(autoFetch(express, pAddress = "hasPermission", cAddress = "Admin", mAddress = "middleware"))
|
|
||||||
|
|
||||||
app.use('/uploads', expressSharp({
|
|
||||||
imageAdapter: new FsAdapter(path.join(__dirname, 'uploads')),
|
|
||||||
}));
|
|
||||||
app.use('/vid', videovalidate.run, expressSharp({
|
|
||||||
imageAdapter: new FsAdapter(path.join(__dirname, 'Videos')),
|
|
||||||
}));
|
|
||||||
|
|
||||||
//Error handler
|
|
||||||
app.use(errorHandler.run);
|
|
||||||
|
|
||||||
//Init site data
|
|
||||||
Site.findOne({ profile: "main" }).then(async (data) => {
|
|
||||||
if (!data) {
|
|
||||||
await Site.create({
|
|
||||||
profile: "main",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).catch(async (err) => {
|
|
||||||
await Site.create({
|
|
||||||
profile: "main",
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
app.listen(port, () => {
|
|
||||||
console.log(`Server runing on port: ${port}`);
|
|
||||||
});
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { ThrottlerModule } from '@nestjs/throttler';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
// ServeStaticModule.forRoot({
|
||||||
|
// rootPat h: join(__dirname, '..', 'public'),
|
||||||
|
// }),
|
||||||
|
// ConfigModule.forRoot({
|
||||||
|
// isGlobal: true,
|
||||||
|
// }),
|
||||||
|
ThrottlerModule.forRoot({
|
||||||
|
ttl: 60,
|
||||||
|
limit: 10,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
controllers: [],
|
||||||
|
providers: [],
|
||||||
|
})
|
||||||
|
export class AppModule {}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{ "mongoDb": "mongodb://127.0.0.1:27017/admin" }
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
const pathes = {
|
||||||
|
staticFiles: './../public',
|
||||||
|
viewFiles: './views',
|
||||||
|
userQrCodeFiles: '../public/user/qrCodes',
|
||||||
|
uploadedFiles: '/files/',
|
||||||
|
tinymceUpload: '/tinymceUpload/',
|
||||||
|
// siteUrl: 'http://172.16.27.32/api',
|
||||||
|
// clientUrl: 'http://172.16.27.32/api',
|
||||||
|
siteUrl: 'http://localhost:4123',
|
||||||
|
clientUrl: 'http://localhost:4123',
|
||||||
|
appRoot: path.resolve(),
|
||||||
|
};
|
||||||
|
|
||||||
|
export default pathes;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"title": "DLearn ",
|
||||||
|
"description": "DLearn APIs",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"tag": "DLearn Apis"
|
||||||
|
}
|
||||||
+65
@@ -0,0 +1,65 @@
|
|||||||
|
import { NestFactory } from '@nestjs/core';
|
||||||
|
import * as session from 'express-session';
|
||||||
|
import { AppModule } from './app.module';
|
||||||
|
import mongoose from 'mongoose';
|
||||||
|
import * as dotenv from 'dotenv';
|
||||||
|
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
||||||
|
import * as swaggerConfig from './config/swagger.json';
|
||||||
|
import { ValidationPipe } from '@nestjs/common';
|
||||||
|
import { NestExpressApplication } from '@nestjs/platform-express';
|
||||||
|
import paths from './config/paths';
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
async function bootstrap() {
|
||||||
|
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
|
||||||
|
cors: true,
|
||||||
|
});
|
||||||
|
const db =
|
||||||
|
// app.setGlobalPrefix('api/v1');
|
||||||
|
// app.useGlobalInterceptors(new ClassSerializerInterceptor(app.get(Reflector)));
|
||||||
|
app.useGlobalPipes(new ValidationPipe());
|
||||||
|
app.use(
|
||||||
|
session({
|
||||||
|
name: 'DLearn',
|
||||||
|
secret: '68yzNk6SQuPFY#WREFDF^&%TERGH765rtgfHJ%$ERFDF@#$!dg^5r%aALM1',
|
||||||
|
resave: false,
|
||||||
|
saveUninitialized: false,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
app.useStaticAssets(paths.staticFiles);
|
||||||
|
app.setBaseViewsDir(paths.viewFiles);
|
||||||
|
app.setViewEngine('ejs');
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
res.header('Access-Control-Allow-Origin', '*');
|
||||||
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||||
|
res.setHeader('X-Powered-By', 'NestJs');
|
||||||
|
res.setHeader(
|
||||||
|
'Access-Control-Allow-Methods',
|
||||||
|
'GET, POST, OPTIONS, PUT, PATCH, DELETE',
|
||||||
|
);
|
||||||
|
res.setHeader(
|
||||||
|
'Access-Control-Allow-Headers',
|
||||||
|
'X-Requested-With,content-type',
|
||||||
|
);
|
||||||
|
res.setHeader('Access-Control-Allow-Credentials', true);
|
||||||
|
res.header(
|
||||||
|
'Access-Control-Allow-Headers',
|
||||||
|
'Origin, X-Requested-With, Content-Type, Accept',
|
||||||
|
);
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
mongoose.connect(
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
|
`mongodb://${process.env.MONGO_CONNECTION_HOST}:${process.env.MONGO_CONNECTION_PORT}/${process.env.MONGO_CONNECTION_NAME}`,
|
||||||
|
);
|
||||||
|
const config = new DocumentBuilder()
|
||||||
|
.setTitle(swaggerConfig.title)
|
||||||
|
.setDescription(swaggerConfig.description)
|
||||||
|
.setVersion(swaggerConfig.version)
|
||||||
|
.addTag(swaggerConfig.tag)
|
||||||
|
.build();
|
||||||
|
const document = SwaggerModule.createDocument(app, config);
|
||||||
|
SwaggerModule.setup('api/v1', app, document);
|
||||||
|
await app.listen(3000);
|
||||||
|
}
|
||||||
|
bootstrap();
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/* eslint-disable no-param-reassign */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A mongoose schema plugin which applies the following in the toJSON transform call:
|
||||||
|
* - removes __v, createdAt, updatedAt, and any path that has private: true
|
||||||
|
* - replaces _id with id
|
||||||
|
*/
|
||||||
|
|
||||||
|
const deleteAtPath = (obj, path, index) => {
|
||||||
|
if (index === path.length - 1) {
|
||||||
|
delete obj[path[index]];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
deleteAtPath(obj[path[index]], path, index + 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const cleanJson = (schema) => {
|
||||||
|
let transform;
|
||||||
|
if (schema.options.toJSON && schema.options.toJSON.transform) {
|
||||||
|
transform = schema.options.toJSON.transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
schema.options.toJSON = Object.assign(schema.options.toJSON || {}, {
|
||||||
|
transform(doc, ret, options) {
|
||||||
|
Object.keys(schema.paths).forEach((path) => {
|
||||||
|
if (schema.paths[path].options && schema.paths[path].options.private) {
|
||||||
|
deleteAtPath(ret, path.split('.'), 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ret.id = ret._id.toString();
|
||||||
|
delete ret._id;
|
||||||
|
delete ret.isDeleted;
|
||||||
|
delete ret.deletedAt;
|
||||||
|
delete ret.__v;
|
||||||
|
delete ret.updatedAt;
|
||||||
|
if (transform) {
|
||||||
|
return transform(doc, ret, options);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export default cleanJson;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
import cleanJson from './cleanJson.plugin';
|
||||||
|
export { cleanJson };
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"declaration": true,
|
||||||
|
"removeComments": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"target": "es2017",
|
||||||
|
"sourceMap": true,
|
||||||
|
"outDir": "./dist",
|
||||||
|
"baseUrl": "./",
|
||||||
|
"incremental": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strictNullChecks": false,
|
||||||
|
"noImplicitAny": false,
|
||||||
|
"strictBindCallApply": false,
|
||||||
|
"forceConsistentCasingInFileNames": false,
|
||||||
|
"noFallthroughCasesInSwitch": false,
|
||||||
|
"resolveJsonModule": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Asanmarket
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Asanmarket
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# Asanmarket
|
|
||||||
Reference in New Issue
Block a user