From 049b1e597ef551176370ce83c152d8a17778b49f Mon Sep 17 00:00:00 2001 From: ilyas Date: Sun, 7 Nov 2021 19:58:57 +0500 Subject: [PATCH 01/23] Refactoring --- package.json | 10 +- .../builtinModules/auth/handlers/index.ts | 243 ------------------ src/framework/builtinModules/auth/index.ts | 117 --------- .../forgetPassword/handlers/index.ts | 75 ------ .../builtinModules/forgetPassword/index.ts | 151 ----------- .../defaultConfiguration.ts | 2 +- src/framework/graphql/crudGenerator.ts | 75 +----- src/framework/graphql/generalSchema.ts | 4 - src/framework/graphql/loadAllModules.ts | 16 -- .../initialization/checkInstalledPackages.ts | 2 +- src/framework/initialization/startServers.ts | 12 +- src/framework/security/createJwtToken.ts | 12 - src/framework/types/models.ts | 8 - src/framework/types/override.ts | 13 - 14 files changed, 16 insertions(+), 724 deletions(-) delete mode 100644 src/framework/builtinModules/auth/handlers/index.ts delete mode 100644 src/framework/builtinModules/auth/index.ts delete mode 100644 src/framework/builtinModules/forgetPassword/handlers/index.ts delete mode 100644 src/framework/builtinModules/forgetPassword/index.ts delete mode 100644 src/framework/security/createJwtToken.ts diff --git a/package.json b/package.json index f6f01fdc..f73fdb0c 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "prettier" ], "dependencies": { - "apollo-server": "^2.8.2", + "apollo-server": "^3.5.0", "apollo-server-express": "^2.9.4", "aws-sdk": "^2.820.0", "bcryptjs": "^2.4.3", @@ -45,11 +45,10 @@ "cors": "^2.8.5", "dropbox": "^8.2.0", "express": "^4.17.1", - "graphql": "^14.1.1", + "graphql": "^15.7.2", "graphql-fields": "^2.0.3", "graphql-type-json": "^0.3.2", "handlebars": "^4.5.3", - "jsonwebtoken": "^8.4.0", "lodash": "^4.17.15", "log-symbols": "^3.0.0", "moment": "^2.23.0", @@ -59,11 +58,7 @@ "mysqldump": "^3.2.0", "node-cron": "^2.0.3", "nodemailer": ">=6.4.16", - "pg": "^7.18.2", - "pg-hstore": "^2.3.3", - "request-ip": "^2.1.3", "sequelize": "^6.3.5", - "shelljs": "^0.8.3", "socket.io": "^4.1.3", "winston": "^3.1.0", "ws": "^8.0.0" @@ -74,7 +69,6 @@ "@types/dotenv": "^4.0.3", "@types/express": "^4.16.0", "@types/http-codes": "^1.0.1", - "@types/jsonwebtoken": "^7.2.8", "@types/knex": "^0.14.19", "@types/morgan": "^1.7.35", "@types/node": "^9.6.55", diff --git a/src/framework/builtinModules/auth/handlers/index.ts b/src/framework/builtinModules/auth/handlers/index.ts deleted file mode 100644 index 99162484..00000000 --- a/src/framework/builtinModules/auth/handlers/index.ts +++ /dev/null @@ -1,243 +0,0 @@ -import moment from "moment"; -import createJwtToken from "./../../../../framework/security/createJwtToken"; -import { ApolloError } from "apollo-server"; -import { - verifyPassword, - generateHashPassword, -} from "./../../../../framework/helpers/auth"; -import { get } from "lodash"; - -export const signup = async function (obj) { - const { userModel, data, emailTemplates, sendEmail, configuration } = obj; - const { sendEmailOnSignup } = get( - configuration, - "email.sendEmailOnSignup", - true - ); - let { email, password, confirmPassword, ...restData } = data; - if (password !== confirmPassword) - throw new ApolloError("Passwords doesn't match."); - let user = await userModel.findOne({ - where: { - email: email, - }, - }); - if (user) throw new ApolloError("Email is already used"); - var hash = generateHashPassword(password); - let newUser = await userModel.create({ - email: email, - referer: get(data, "referer", ""), - superUser: false, - name: get(data, "name", ""), - accessToken: await createJwtToken({ - email: email, - for: "authentication", - expiresIn: moment().add(5, "days").unix(), - }), - refreshToken: await createJwtToken({ - email: email, - for: "refreshToken", - expiresIn: moment().add(5, "days").unix(), - }), - isActivated: false, - isSuperUser: get(data, "isSuperUser", false), - activationToken: - Math.random().toString(36).substring(2) + - Math.random().toString(36).substring(2) + - Math.random().toString(36).substring(2), - password: hash, - ...restData, - }); - let userInstance = newUser; - if (sendEmailOnSignup) { - await sendEmail( - emailTemplates.welcome, - { - email: newUser.email, - username: newUser.email, - date: moment().format("dddd, MMMM Do YYYY, h:mm:ss a"), - siteName: process.env.name, - activationUrl: `${process.env.frontendAppUrl}/activate-account/`, - activationToken: newUser.activationToken, - }, - { - from: process.env.mailerServiceUsername, - to: newUser.email, - subject: `Welcome to ${process.env.name}`, - } - ); - } - return { - message: "Signup Completed", - returning: userInstance, - }; -}; -export const login = async function ( - obj, - NoUserFoundMessage: string = '"No User found with such email"' -) { - const { userModel, data } = obj; - const { email, password } = data; - const restArgs = get(data, "restArgs", {}); - let user = await userModel.findOne({ - where: { - email: email, - ...restArgs, - }, - }); - if (!user) { - throw new ApolloError(NoUserFoundMessage); - } - let comparePassword = await verifyPassword(password, user.password); - if (!comparePassword) { - throw new ApolloError("Incorrect Password"); - } - let token = await createJwtToken({ - email: email, - for: "authentication", - expiresIn: moment().add(5, "days").unix(), - }); - user = await user.update({ - accessToken: token, - }); - return { - message: "Login Completed", - returning: user, - }; -}; -export const twoFactorLogin = async function (obj) { - const { userModel, emailTemplates, sendEmail, data } = obj; - const { email } = data; - let user = await userModel.findOne({ - where: { - email: email, - }, - }); - if (!user) { - throw new ApolloError("Incorrect email."); - } - const twoFactorCode = `Code-` + Math.floor(Math.random() * 60000 + 5000); - user = await user.update({ - twoFactorCode: twoFactorCode, - }); - let userInstance = user; - await sendEmail( - emailTemplates.twoFactorLogin, - { - username: user.email, - siteName: process.env.name, - twoFactorCode: twoFactorCode, - }, - { - from: process.env.mailerServiceUsername, - to: user.email, - subject: `${twoFactorCode} is your authentication number - ${process.env.name}`, - } - ); - return { - message: `A code has been sent to your email which is ${userInstance.email}`, - }; -}; -export const twoFactorLoginValidate = async function (obj) { - const { userModel, data } = obj; - const { twoFactorCode } = data; - let user = await userModel.findOne({ - where: { - twoFactorCode: twoFactorCode, - }, - }); - if (!user) { - throw new ApolloError("Incorrect twoFactorCode or already used."); - } - user = await user.update({ - twoFactorCode: "", - accessToken: await createJwtToken({ - email: user.email, - for: "authentication", - }), - refreshToken: await createJwtToken({ - email: user.email, - for: "authentication", - }), - }); - return user; -}; -export const loginWithAccessToken = async function (obj) { - const { userModel, data } = obj; - const { accessToken } = data; - let user = await userModel.findOne({ - where: { - accessToken: accessToken, - }, - }); - if (!user) { - throw new ApolloError("Access token is missing."); - } - user = await user.update({ - accessToken: await createJwtToken({ - email: user.email, - for: "authentication", - }), - refreshToken: await createJwtToken({ - email: user.email, - for: "authentication", - }), - }); - return user; -}; -export const activateAccount = async function (obj) { - const { userModel, emailTemplates, sendEmail, data } = obj; - const { activationToken } = data; - let user = await userModel.findOne({ - where: { - activation_token: activationToken, - }, - }); - if (!user) { - throw new ApolloError("No User found or account is already is activated."); - } - user = await user.update({ - is_activated: true, - activation_token: "", - }); - let userInstance = user; - (await sendEmail) && - sendEmail( - emailTemplates.accountActivated, - { - username: user.email, - siteName: process.env.name, - }, - { - from: process.env.mailerServiceUsername, - to: user.email, - subject: `Account activated ${process.env.name}`, - } - ); - return { - message: "Account activated", - }; -}; -export const refreshTokenHandler = async function (obj) { - const { userModel, data } = obj; - const { refreshToken } = data; - let user = await userModel.findOne({ - where: { - refreshToken: refreshToken, - }, - }); - if (!user) { - throw new ApolloError("Unauthorized, Missing refresh token."); - } - user = await user.update({ - accessToken: await createJwtToken({ - email: user.email, - for: "authentication", - }), - refreshToken: await createJwtToken({ - email: user.email, - for: "authentication", - }), - }); - return user; -}; diff --git a/src/framework/builtinModules/auth/index.ts b/src/framework/builtinModules/auth/index.ts deleted file mode 100644 index 67556003..00000000 --- a/src/framework/builtinModules/auth/index.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { - login, - signup, - loginWithAccessToken, - activateAccount, - refreshTokenHandler, - twoFactorLogin, - twoFactorLoginValidate, -} from "./handlers/index"; - -export default { - name: "Auth", - useDatabase: false, - graphql: { - schema: ` - input TwoFactorCodeInput { - twoFactorCode: String! - } - input AccessTokenInput { - accessToken: String! - } - input ActivationTokenInput { - activationToken: String! - } - input RefreshTokenInput { - refreshToken: String! - } - input loginInput { - email: String! - password: String! - } - type AuthResponse { - message: String - returning: User - } - `, - mutation: { - schema: ` - twoFactorLogin(input: EmailInputFP): SuccessResponse - twoFactorLoginValidate(input: TwoFactorCodeInput): User - loginWithAccessToken(input: AccessTokenInput): User - activateAccount(input: ActivationTokenInput): SuccessResponse - signup(input: SignupInput): AuthResponse - login(input: loginInput): AuthResponse - refreshToken(input: RefreshTokenInput): User - `, - resolvers: { - twoFactorLogin: async (_: any, args: any, context: any, info: any) => { - return await twoFactorLogin({ - userModel: context.wertik.models["User"], - emailTemplates: context.wertik.emailTemplates, - sendEmail: context.wertik.sendEmail, - data: args.input, - }); - }, - twoFactorLoginValidate: async ( - _: any, - args: any, - context: any, - info: any - ) => { - return await twoFactorLoginValidate({ - userModel: context.wertik.models["User"], - data: args.input, - }); - }, - loginWithAccessToken: async ( - _: any, - args: any, - context: any, - info: any - ) => { - return await loginWithAccessToken({ - userModel: context.wertik.models["User"], - data: args.input, - }); - }, - activateAccount: async (_: any, args: any, context: any, info: any) => { - return await activateAccount({ - userModel: context.wertik.models["User"], - emailTemplates: context.wertik.emailTemplates, - sendEmail: context.wertik.sendEmail, - data: args.input, - }); - }, - signup: async (_: any, args: any, context: any, info: any) => { - return await signup({ - userModel: context.wertik.models["User"], - emailTemplates: context.wertik.emailTemplates, - sendEmail: context.wertik.sendEmail, - data: args.input, - configuration: context.wertik.configuration, - }); - }, - login: async (_: any, args: any, context: any, info: any) => { - return await login({ - userModel: context.wertik.models["User"], - data: args.input, - }); - }, - refreshToken: async (_: any, args: any, context: any, info: any) => { - return await refreshTokenHandler({ - userModel: context.wertik.models["User"], - data: args.input, - }); - }, - }, - }, - query: { - schema: ``, - resolvers: {}, - }, - }, - restApi: { - endpoints: [], - }, -}; diff --git a/src/framework/builtinModules/forgetPassword/handlers/index.ts b/src/framework/builtinModules/forgetPassword/handlers/index.ts deleted file mode 100644 index c97a0d5b..00000000 --- a/src/framework/builtinModules/forgetPassword/handlers/index.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { ApolloError } from "apollo-server"; -import createJwtToken from "./../../../security/createJwtToken"; -import { randomString } from "./../../../helpers/index"; -import moment from "moment"; -import { generateHashPassword } from "../../../helpers/auth"; - -export const requestPasswordResetHandler = async function (obj) { - const { userModel, forgetPasswordModel, data, emailTemplates, sendEmail } = - obj; - let user = await userModel.findOne({ - where: { - email: data.email, - }, - }); - if (!user.instance) throw new ApolloError("No User found with such email."); - let forgetPassword = await forgetPasswordModel.findOne({ - where: { - email: data.email, - }, - }); - if (forgetPassword.instance) { - await forgetPassword.delete(); - } - let token = randomString(24, "MYNAMEISILYASKARIMANDIVETHESENUMBERS123456789"); - await forgetPasswordModel.create({ - token: token, - email: user.instance.email, - user: user.instance.id, - expiresIn: moment().add(30, "m").unix(), - }); - await sendEmail( - emailTemplates.requestPasswordReset, - { - email: user.instance.email, - nextMinutes: moment().add(30, "m").format("LLLL"), - token: token, - siteName: process.env.name, - frontendAppPasswordResetUrl: process.env.frontendAppPasswordResetUrl, - }, - { - from: process.env.mailerServiceUsername, - to: user.instance.email, - subject: `Reset Password`, - } - ); - return { - message: "Please check your email", - }; -}; - -export const resetPasswordHandler = async function (obj) { - const { userModel, forgetPasswordModel, data } = obj; - const { token, password, confirmPassword } = data; - let forgetPassword = await forgetPasswordModel.findOne({ - where: { - token: token, - }, - }); - if (!forgetPassword.instance) - throw new ApolloError("Token mismatch or already used."); - let user = await userModel.findOne({ - where: { - email: forgetPassword.instance.email, - }, - }); - if (!user.instance) throw new ApolloError("User not found"); - const hash = generateHashPassword(password); - await user.update({ - password: hash, - }); - await forgetPassword.delete(); - return { - message: "Password changed", - }; -}; diff --git a/src/framework/builtinModules/forgetPassword/index.ts b/src/framework/builtinModules/forgetPassword/index.ts deleted file mode 100644 index e0082e2e..00000000 --- a/src/framework/builtinModules/forgetPassword/index.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { requestPasswordResetHandler, resetPasswordHandler } from "./handlers"; -import getRequestedFieldsFromResolverInfo from "./../../helpers/getRequestedFieldsFromResolverInfo"; - -export default { - name: "ForgetPassword", - graphql: { - schema: ` - type ForgetPassword { - id: Int - name: String - email: String - user: User - user_id: Int - token: String - created_at: String - updated_at: String - } - input requestPasswordResetInput { - email: String! - } - input resetPasswordInput { - token: String! - password: String! - confirmPassword: String! - } - input ForgetPasswordInput { - id: Int - name: String - email: String - user_id: Int - token: String - } - `, - customResolvers: {}, - mutation: { - schema: ` - requestPasswordReset(input: requestPasswordResetInput): SuccessResponse - resetPassword(input: resetPasswordInput): SuccessResponse - `, - resolvers: { - requestPasswordReset: async ( - _: any, - args: any, - context: any, - info: any - ) => { - return await requestPasswordResetHandler({ - userModel: context.wertik.models.User, - forgetPasswordModel: context.wertik.models.ForgetPassword, - data: args.input, - emailTemplates: context.wertik.emailTemplates, - sendEmail: context.wertik.sendEmail, - }); - }, - resetPassword: async (_: any, args: any, context: any, info: any) => { - return await resetPasswordHandler({ - userModel: context.wertik.models.User, - forgetPasswordModel: context.wertik.models.ForgetPassword, - data: args.input, - }); - }, - }, - }, - query: { - schema: ``, - resolvers: {}, - }, - }, - restApi: { - endpoints: [ - { - path: "/request-password-reset", - methodType: "post", - handler: async function (req, res) { - try { - let response = await requestPasswordResetHandler({ - userModel: req.wertik.models.User, - forgetPasswordModel: req.wertik.models.ForgetPassword, - data: req.body.input, - emailTemplates: req.wertik.emailTemplates, - sendEmail: req.wertik.sendEmail, - }); - res.json({ - message: response, - }); - } catch (e) { - res.json({ - success: false, - message: e.message, - result: {}, - }); - } - }, - }, - { - path: "/reset-password", - methodType: "post", - handler: async function (req, res) { - try { - let response = await resetPasswordHandler({ - userModel: req.wertik.models.User, - forgetPasswordModel: req.wertik.models.ForgetPassword, - data: req.body.input, - }); - res.json({ - message: response, - }); - } catch (e) { - res.json({ - success: false, - message: e.message, - result: {}, - }); - } - }, - }, - ], - }, - database: { - selectIgnoreFields: ["user"], - relationships: { - oneToOne: { - User: { - sourceKey: "user_id", - as: "user", - foreignKey: "id", - }, - }, - }, - sql: { - tableName: "forgetPassword", - fields: { - name: { - type: "String", - }, - email: { - type: "String", - }, - user_id: { - type: "Integer", - }, - token: { - type: "String", - }, - is_deleted: { - type: "INTEGER", - }, - }, - }, - }, -}; diff --git a/src/framework/defaults/defaultConfigurations/defaultConfiguration.ts b/src/framework/defaults/defaultConfigurations/defaultConfiguration.ts index 422c7801..6c159d4a 100644 --- a/src/framework/defaults/defaultConfigurations/defaultConfiguration.ts +++ b/src/framework/defaults/defaultConfigurations/defaultConfiguration.ts @@ -1,7 +1,7 @@ export default { name: "Wertik", builtinModules: - "user,auth,forgetPassword,permission,role,rolePermission,userPermission,userRole,storage,email,backup", + "user,permission,role,rolePermission,userPermission,userRole,storage,email,backup", database: { dbDialect: process.env.dbDialect, dbUsername: process.env.dbUsername, diff --git a/src/framework/graphql/crudGenerator.ts b/src/framework/graphql/crudGenerator.ts index 54c57663..fb0e3b61 100644 --- a/src/framework/graphql/crudGenerator.ts +++ b/src/framework/graphql/crudGenerator.ts @@ -19,7 +19,7 @@ export const generateQueriesCrudSchema = (moduleName: String) => { moduleName )}(filters: [FilterInput]): ${moduleName}`; const viewString = `view${moduleName}(${identityColumn}: ${identityColumnGraphQLType}): ${moduleName}`; - const listString = `list${moduleName}(cache: CacheOptionsInput, pagination: PaginationInput, filters: ${moduleName}FilterInput, sorting: [SortingInput]): ${moduleName}List`; + const listString = `list${moduleName}(pagination: PaginationInput, filters: ${moduleName}FilterInput, sorting: [SortingInput]): ${moduleName}List`; const countString = `count${moduleName}(filters: ${moduleName}FilterInput): Int`; string = ` ${viewString} @@ -30,42 +30,6 @@ export const generateQueriesCrudSchema = (moduleName: String) => { return string; }; -export const generateMutationsCrudSubscriptionSchema = (moduleName: String) => { - return ` - ${moduleName}Deleted: SuccessResponse - ${moduleName}BulkCreated: [${moduleName}] - ${moduleName}BulkUpdated: [${moduleName}] - `; -}; - -export const getSubscriptionConstants = (moduleName: String) => { - return { - deletedModule: `${moduleName}Deleted`, - bulkCreatedModule: `${moduleName}BulkCreated`, - bulkUpdatedModule: `${moduleName}BulkUpdated`, - }; -}; - -export const generateSubscriptionsCrudResolvers = ( - moduleName: String, - pubsub: any -) => { - const { deletedModule, bulkCreatedModule, bulkUpdatedModule } = - getSubscriptionConstants(moduleName); - let object = { - [deletedModule]: { - subscribe: () => pubsub.asyncIterator([deletedModule]), - }, - [bulkCreatedModule]: { - subscribe: () => pubsub.asyncIterator([bulkCreatedModule]), - }, - [bulkUpdatedModule]: { - subscribe: () => pubsub.asyncIterator([bulkUpdatedModule]), - }, - }; - return object; -}; - export const generateMutationsCrudSchema = (moduleName: String) => { const bulkUpdateString = `bulkUpdate${moduleName}(input: [${moduleName}Input]): ${moduleName}BulkMutationResponse`; const bulkCreateString = `bulkCreate${moduleName}(input: [${moduleName}Input]): ${moduleName}BulkMutationResponse`; @@ -79,7 +43,6 @@ export const generateMutationsCrudSchema = (moduleName: String) => { export const generateCrudResolvers = ( module: IConfigurationCustomModule, - pubsub, configuration: IConfiguration ) => { const overrideMutationBulkCreate = get( @@ -162,10 +125,6 @@ export const generateCrudResolvers = ( null ); - const { bulkCreatedModule, bulkUpdatedModule } = getSubscriptionConstants( - module.name - ); - let object = { mutations: { [`bulkDelete${module.name}`]: async ( @@ -228,9 +187,6 @@ export const generateCrudResolvers = ( : args; let model = context.wertik.models[module.name]; let result = await model.bulkCreate(finalArgs.input); - pubsub.publish(bulkCreatedModule, { - [bulkCreatedModule]: result, - }); if (isFunction(afterBulkCreate)) { afterBulkCreate({ mode: "graphql", @@ -281,9 +237,6 @@ export const generateCrudResolvers = ( result.push(a); } } - pubsub.publish(bulkUpdatedModule, { - [bulkUpdatedModule]: result, - }); if (isFunction(afterBulkUpdate)) { afterBulkUpdate({ mode: "graphql", @@ -360,32 +313,20 @@ export const generateCrudResolvers = ( params: { _, args, context, info }, }) : args; - const cacheWith = (args.cache && args.cache.name) || ""; - const cacheValue = context.wertik.cache.get(cacheWith); - if (cacheWith && cacheValue) { - response = cacheValue; - } else { - let model = context.wertik.models[module.name]; - let requestedFields = getRequestedFieldsFromResolverInfo(info); - response = await model.paginate( - finalArgs, - Object.keys(requestedFields.list) - ); - } + let model = context.wertik.models[module.name]; + let requestedFields = getRequestedFieldsFromResolverInfo(info); + response = await model.paginate( + finalArgs, + Object.keys(requestedFields.list) + ); + if (isFunction(afterList)) { afterList({ mode: "graphql", params: { _, args, context, info, instance: response }, }); } - if (cacheWith) { - context.wertik.cache.set( - cacheWith, - response, - (args.cache && args.cache.expiry) || 0 - ); - } return response; }, }, diff --git a/src/framework/graphql/generalSchema.ts b/src/framework/graphql/generalSchema.ts index 3ba8c88e..2bffa3d1 100644 --- a/src/framework/graphql/generalSchema.ts +++ b/src/framework/graphql/generalSchema.ts @@ -93,8 +93,4 @@ export default ` previousPage: Int hasMore: Boolean } - input CacheOptionsInput { - name: String - expiry: Int - } `; diff --git a/src/framework/graphql/loadAllModules.ts b/src/framework/graphql/loadAllModules.ts index 963210db..b525b49c 100644 --- a/src/framework/graphql/loadAllModules.ts +++ b/src/framework/graphql/loadAllModules.ts @@ -4,18 +4,14 @@ import { get, isFunction } from "lodash"; import generalSchema from "./generalSchema"; import { - generateSubscriptionsCrudResolvers, generateQueriesCrudSchema, generateListTypeForModule, - generateMutationsCrudSubscriptionSchema, generateMutationsCrudSchema, generateCrudResolvers, } from "./crudGenerator"; -import { PubSub } from "apollo-server"; import { IConfiguration } from "../types/configuration"; import { GraphQLModuleRelationMapper } from "../moduleRelationships/graphql"; import self from "./self"; -const pubsub = new PubSub(); export default async function (configuration: IConfiguration) { let modulesSchema = ` @@ -118,7 +114,6 @@ export default async function (configuration: IConfiguration) { const crudResolvers = generateCrudResolvers( currentModule, - pubsub, configuration ); @@ -129,13 +124,6 @@ export default async function (configuration: IConfiguration) { const crudQuerySchema = generateQueriesCrudSchema(currentModuleName); const crudQueryResolvers = crudResolvers.queries; - const crudSubscriptionSchema = - generateMutationsCrudSubscriptionSchema(currentModuleName); - const crudSubscriptionResolvers = generateSubscriptionsCrudResolvers( - currentModuleName, - pubsub - ); - modulesQuerySchema = `${modulesQuerySchema} ${crudQuerySchema} `; @@ -153,12 +141,8 @@ export default async function (configuration: IConfiguration) { ...crudMutationResolvers, }; - modulesSubscriptionSchema = - modulesSubscriptionSchema + crudSubscriptionSchema; - appSubscriptions = { ...appSubscriptions, - ...crudSubscriptionResolvers, }; } diff --git a/src/framework/initialization/checkInstalledPackages.ts b/src/framework/initialization/checkInstalledPackages.ts index 69e74fff..2ca27da7 100644 --- a/src/framework/initialization/checkInstalledPackages.ts +++ b/src/framework/initialization/checkInstalledPackages.ts @@ -33,7 +33,7 @@ export default function (configuration: IConfiguration) { check("pg-hstore"); check("pg-native"); } - resolve(); + resolve(true); } catch (e) { reject(e); } diff --git a/src/framework/initialization/startServers.ts b/src/framework/initialization/startServers.ts index 51b33e80..eccf2e5a 100644 --- a/src/framework/initialization/startServers.ts +++ b/src/framework/initialization/startServers.ts @@ -65,16 +65,16 @@ export default function (configuration: IConfiguration, servers: any) { restApi.get("*", restApi404Handler); } httpServer.listen(expressAppPort, () => { + successMessage( + `Express Server Started`, + `http://localhost:${expressAppPort}` + ); if (disableSockets === false) { successMessage( `Socket.IO server running at`, `http://localhost:${expressAppPort}` ); } - successMessage( - `Rest API server started at`, - `http://localhost:${expressAppPort}` - ); if (disableGraphqlVoyager === false) { successMessage( `GraphQL Voyager running at`, @@ -86,10 +86,6 @@ export default function (configuration: IConfiguration, servers: any) { "GraphQL Server started at", `http://localhost:${expressAppPort}${graphql.graphqlPath}` ); - successMessage( - "GraphQL Subscriptions are running at", - `ws://localhost:${expressAppPort}${graphql.subscriptionsPath}` - ); } }); } diff --git a/src/framework/security/createJwtToken.ts b/src/framework/security/createJwtToken.ts deleted file mode 100644 index 4892ae56..00000000 --- a/src/framework/security/createJwtToken.ts +++ /dev/null @@ -1,12 +0,0 @@ -let moment = require("moment"); -let jwt = require("jsonwebtoken"); -import { get, has } from "lodash"; - -export default async function createJwtToken(data: any) { - if (typeof data !== "object") { - throw "Data must be object"; - } - let firstArgument = data; - let secret = process.env.jwtSecret || "asdasdasd"; - return await jwt.sign(firstArgument, secret, { expiresIn: data.expiresIn }); -} diff --git a/src/framework/types/models.ts b/src/framework/types/models.ts index 51c8d5af..13988a59 100644 --- a/src/framework/types/models.ts +++ b/src/framework/types/models.ts @@ -26,14 +26,6 @@ export interface IUser { referer: String; } -export interface IForgetPassword { - id: Number; - name: String; - email: String; - user: any; - token: String; -} - export interface IRolePermission { id: Number; role: any; diff --git a/src/framework/types/override.ts b/src/framework/types/override.ts index ef2c3f01..fba2cba0 100644 --- a/src/framework/types/override.ts +++ b/src/framework/types/override.ts @@ -49,21 +49,8 @@ export interface IBuiltinModuleOverrideAuth { refreshToken: Function; }; } -export interface IBuiltinModuleOverrideForgetPassword { - graphql: { - mutation: { - requestPasswordReset: Function; - resetPassword: Function; - }; - }; - restApi: { - requestPasswordReset: Function; - resetPassword: Function; - }; -} export interface IConfigurationOverride { - ForgetPassword: IBuiltinModuleOverrideForgetPassword; Role: IBuiltinModuleOverride; UserPermission: IBuiltinModuleOverride; Permission: IBuiltinModuleOverride; From 634049ec0f8c5871fd8588cf60657a0af833dadc Mon Sep 17 00:00:00 2001 From: ilyas Date: Sun, 7 Nov 2021 20:03:48 +0500 Subject: [PATCH 02/23] Cleanup --- package.json | 2 - .../builtinModules/permission/index.ts | 79 ------------------ src/framework/builtinModules/role/index.ts | 74 ----------------- .../builtinModules/rolePermission/index.ts | 80 ------------------ src/framework/builtinModules/user/index.ts | 15 +--- .../builtinModules/userPermission/index.ts | 81 ------------------ .../builtinModules/userRole/index.ts | 83 ------------------- .../defaultConfiguration.ts | 60 +------------- 8 files changed, 3 insertions(+), 471 deletions(-) delete mode 100644 src/framework/builtinModules/permission/index.ts delete mode 100644 src/framework/builtinModules/role/index.ts delete mode 100644 src/framework/builtinModules/rolePermission/index.ts delete mode 100644 src/framework/builtinModules/userPermission/index.ts delete mode 100644 src/framework/builtinModules/userRole/index.ts diff --git a/package.json b/package.json index f73fdb0c..63db8be8 100644 --- a/package.json +++ b/package.json @@ -76,10 +76,8 @@ "@types/winston": "^2.4.4", "concurrently": "^3.6.1", "dotenv": "^6.2.0", - "module-alias": "^2.1.0", "nodemon": "^1.18.9", "prettier": "^2.3.2", - "sequelize-cli": "^5.4.0", "tslint": "^5.17.0", "typescript": "^3.5.1" } diff --git a/src/framework/builtinModules/permission/index.ts b/src/framework/builtinModules/permission/index.ts deleted file mode 100644 index 97b76983..00000000 --- a/src/framework/builtinModules/permission/index.ts +++ /dev/null @@ -1,79 +0,0 @@ -export default { - name: "Permission", - graphql: { - schema: ` - type Permission { - id: Int - name: String - cant: String - can: String - created_by: User - created_by_id: Int - created_at: String - updated_at: String - user_permissions: UserPermissionList - role_permissions: RolePermissionList - } - input PermissionInput { - id: Int - name: String - cant: String - can: String - created_by_id: Int - } - - `, - mutation: { - schema: ``, - resolvers: {}, - }, - query: { - schema: ``, - resolvers: {}, - }, - }, - restApi: {}, - database: { - selectIgnoreFields: ["user_permissions", "role_permissions", "created_by"], - relationships: { - oneToMany: { - UserPermission: { - as: "user_permissions", - foreignKey: "permission_id", - }, - RolePermission: { - as: "role_permissions", - foreignKey: "permission_id", - }, - }, - oneToOne: { - User: { - as: "created_by", - foreignKey: "id", - sourceKey: "created_by_id", - }, - }, - }, - sql: { - tableName: "permission", - fields: { - name: { - type: "STRING", - unique: true, - }, - cant: { - type: "STRING", - }, - can: { - type: "STRING", - }, - is_deleted: { - type: "INTEGER", - }, - created_by_id: { - type: "INTEGER", - }, - }, - }, - }, -}; diff --git a/src/framework/builtinModules/role/index.ts b/src/framework/builtinModules/role/index.ts deleted file mode 100644 index 6b676827..00000000 --- a/src/framework/builtinModules/role/index.ts +++ /dev/null @@ -1,74 +0,0 @@ -export default { - name: "Role", - graphql: { - schema: ` - type Role { - id: Int - name: String - default_permissions: String - created_by: User - created_by_id: Int - is_deleted: Boolean - created_at: String - updated_at: String - user_roles: UserRoleList - role_permissions: RolePermissionList - } - input RoleInput { - id: Int - default_permissions: String - created_by_id: Int - name: String - } - `, - mutation: { - schema: ``, - resolvers: {}, - }, - query: { - schema: ``, - resolvers: {}, - }, - }, - restApi: {}, - database: { - selectIgnoreFields: ["user_roles", "role_permissions", "created_by"], - relationships: { - oneToMany: { - UserRole: { - as: "user_roles", - foreignKey: "role_id", - }, - RolePermission: { - as: "role_permissions", - foreignKey: "role_id", - }, - }, - oneToOne: { - User: { - as: "created_by", - foreignKey: "id", - sourceKey: "created_by_id", - }, - }, - }, - sql: { - tableName: "role", - fields: { - name: { - type: "STRING", - unique: true, - }, - default_permissions: { - type: "STRING", - }, - is_deleted: { - type: "INTEGER", - }, - created_by_id: { - type: "INTEGER", - }, - }, - }, - }, -}; diff --git a/src/framework/builtinModules/rolePermission/index.ts b/src/framework/builtinModules/rolePermission/index.ts deleted file mode 100644 index 1952e5a9..00000000 --- a/src/framework/builtinModules/rolePermission/index.ts +++ /dev/null @@ -1,80 +0,0 @@ -export default { - name: "RolePermission", - graphql: { - schema: ` - type RolePermission { - id: Int - name: String - role: Role - role_id: Int - permission: Permission - permission_id: Int - created_by: User - created_by_id: Int - created_at: String - updated_at: String - } - input RolePermissionInput { - id: Int - name: String - role_id: Int - permission_id: Int - created_by_id: Int - } - `, - customResolvers: {}, - mutation: { - schema: ``, - resolvers: {}, - }, - query: { - schema: ``, - resolvers: {}, - }, - }, - restApi: {}, - database: { - selectIgnoreFields: ["permission", "role", "created_by"], - relationships: { - belongsTo: { - Permission: { - sourceKey: "permission_id", - as: "permission", - foreignKey: "id", - }, - Role: { - sourceKey: "role_id", - as: "role", - foreignKey: "id", - }, - }, - oneToOne: { - User: { - as: "created_by", - foreignKey: "id", - sourceKey: "created_by_id", - }, - }, - }, - sql: { - tableName: "rolePermission", - fields: { - name: { - type: "STRING", - }, - role_id: { - type: "INTEGER", - }, - permission_id: { - type: "INTEGER", - }, - is_deleted: { - type: "INTEGER", - }, - created_by_id: { - type: "INTEGER", - }, - }, - }, - }, -}; diff --git a/src/framework/builtinModules/user/index.ts b/src/framework/builtinModules/user/index.ts index 58ee9971..4a8a63a3 100644 --- a/src/framework/builtinModules/user/index.ts +++ b/src/framework/builtinModules/user/index.ts @@ -18,8 +18,6 @@ export default { referer: String created_at: String updated_at: String - user_roles: UserRoleList - user_permissions: UserPermissionList } input UserInput { id: Int @@ -54,18 +52,9 @@ export default { }, restApi: {}, database: { - selectIgnoreFields: ["user_permissions", "user_roles"], + selectIgnoreFields: [], relationships: { - oneToMany: { - UserRole: { - as: "user_roles", - foreignKey: "user_id", - }, - UserPermission: { - as: "user_permissions", - foreignKey: "user_id", - }, - }, + oneToMany: {}, }, sql: { tableName: "user", diff --git a/src/framework/builtinModules/userPermission/index.ts b/src/framework/builtinModules/userPermission/index.ts deleted file mode 100644 index a43dd73e..00000000 --- a/src/framework/builtinModules/userPermission/index.ts +++ /dev/null @@ -1,81 +0,0 @@ -export default { - name: "UserPermission", - graphql: { - schema: ` - type UserPermission { - id: Int - name: String - user: User - user_id: Int - permission: Permission - permission_id: Int - created_by: User - created_by_id: Int - created_at: String - updated_at: String - } - input UserPermissionInput { - id: Int - name: String - user_id: Int - permission_id: Int - } - `, - customResolvers: {}, - mutation: { - schema: ``, - resolvers: {}, - }, - query: { - schema: ``, - resolvers: {}, - }, - }, - restApi: {}, - database: { - selectIgnoreFields: ["user", "permission", "created_by"], - relationships: { - belongsTo: { - Permission: { - sourceKey: "permission_id", - as: "permission", - foreignKey: "id", - }, - }, - oneToOne: { - User: [ - { - sourceKey: "created_by_id", - as: "created_by", - foreignKey: "id", - }, - { - sourceKey: "user_id", - as: "user", - foreignKey: "id", - }, - ], - }, - }, - sql: { - tableName: "userPermission", - fields: { - name: { - type: "STRING", - }, - user_id: { - type: "INTEGER", - }, - permission_id: { - type: "INTEGER", - }, - is_deleted: { - type: "INTEGER", - }, - created_by_id: { - type: "INTEGER", - }, - }, - }, - }, -}; diff --git a/src/framework/builtinModules/userRole/index.ts b/src/framework/builtinModules/userRole/index.ts deleted file mode 100644 index 0f9fe9e3..00000000 --- a/src/framework/builtinModules/userRole/index.ts +++ /dev/null @@ -1,83 +0,0 @@ -export default { - name: "UserRole", - graphql: { - schema: ` - type UserRole { - id: Int - name: String - user: User - user_id: Int - role: Role - role_id: Int - created_by: User - created_by_id: Int - created_at: String - updated_at: String - } - input UserRoleInput { - id: Int - name: String - user_id: Int - role_id: Int - created_by_id: Int - } - `, - customResolvers: {}, - mutation: { - schema: ``, - resolvers: {}, - }, - query: { - schema: ``, - resolvers: {}, - }, - }, - - restApi: {}, - database: { - selectIgnoreFields: ["user", "role", "created_by"], - relationships: { - belongsTo: { - Role: { - sourceKey: "role_id", - as: "role", - foreignKey: "id", - }, - }, - oneToOne: { - User: [ - { - sourceKey: "user_id", - as: "user", - foreignKey: "id", - }, - { - sourceKey: "created_by_id", - as: "created_by", - foreignKey: "id", - }, - ], - }, - }, - sql: { - tableName: "userRole", - fields: { - name: { - type: "STRING", - }, - user_id: { - type: "INTEGER", - }, - role_id: { - type: "INTEGER", - }, - is_deleted: { - type: "INTEGER", - }, - created_by_id: { - type: "INTEGER", - }, - }, - }, - }, -}; diff --git a/src/framework/defaults/defaultConfigurations/defaultConfiguration.ts b/src/framework/defaults/defaultConfigurations/defaultConfiguration.ts index 6c159d4a..a6f8229d 100644 --- a/src/framework/defaults/defaultConfigurations/defaultConfiguration.ts +++ b/src/framework/defaults/defaultConfigurations/defaultConfiguration.ts @@ -95,65 +95,7 @@ export default { }, }, restApi: { - endpoints: [ - { - path: "/relations", - methodType: "get", - handler: async function (req, res) { - const models = req.wertik.models; - const { UserPermission, User, Permission, UserRole, Role } = - models; - const All = await User.findOne({ - where: { - id: 1, - }, - attributes: ["id", "email"], - include: [ - { - model: UserRole, - as: "user_roles", - attributes: ["id", "user_id", "role_id"], - include: [ - { - model: Role, - as: "role", - attributes: ["id", "name"], - }, - { - model: User, - as: "user", - attributes: ["id", "email"], - }, - ], - }, - { - model: UserPermission, - as: "user_permissions", - attributes: ["id", "user_id", "permission_id"], - include: [ - { - model: User, - as: "user", - attributes: ["id", "email"], - }, - { - model: Permission, - as: "permission", - attributes: ["id", "can", "cant"], - }, - ], - }, - ], - }); - res.json({ - message: true, - data: { - user: All, - }, - }); - }, - }, - ], + endpoints: [], }, database: { sql: { From 5dddffbfc1fc23926c82447003a1f77e2e99589a Mon Sep 17 00:00:00 2001 From: ilyas Date: Sun, 7 Nov 2021 20:12:17 +0500 Subject: [PATCH 03/23] More Cleanup --- src/framework/database/helpers/stats.ts | 143 ------------------------ src/framework/database/loadTables.ts | 2 - src/framework/defaults/options/index.ts | 6 - src/framework/graphql/generalSchema.ts | 11 -- src/framework/graphql/index.ts | 2 +- src/framework/reporting/index.ts | 122 -------------------- 6 files changed, 1 insertion(+), 285 deletions(-) delete mode 100644 src/framework/database/helpers/stats.ts delete mode 100644 src/framework/reporting/index.ts diff --git a/src/framework/database/helpers/stats.ts b/src/framework/database/helpers/stats.ts deleted file mode 100644 index 1190594e..00000000 --- a/src/framework/database/helpers/stats.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { - getQueryForLast7Days, - getQueryForLastYear, - getQueryForThisYear, - getQueryForThisMonth, - getQueryForLastMonth, - getQueryForThisWeek, - getQueryForToday, - getQueryForLast90Days, -} from "../../reporting/index"; -import { get } from "lodash"; - -export default function (database, model) { - return function (requestedReports) { - return new Promise(async (resolve, reject) => { - try { - let statsInfo = { - total_count: null, - total_created_today: null, - total_created_this_week: null, - total_created_last_7_days: null, - total_created_this_month: null, - total_created_last_month: null, - total_created_last_90_days: null, - total_created_last_year: null, - total_created_this_year: null, - }; - let count, - countLast7Days, - countToday, - countLastYear, - countThisYear, - countThisMonth, - countThisweek, - countLastMonth, - countLast90Days; - let selectOptions = { - type: database.QueryTypes.SELECT, - }; - if (requestedReports.includes("total_count")) { - count = await database.query( - `select count(*) as total_count from ${model.getTableName()}`, - selectOptions - ); - } - if (requestedReports.includes("total_created_last_7_days")) { - countLast7Days = await database.query( - getQueryForLast7Days(model.getTableName()), - selectOptions - ); - } - if (requestedReports.includes("total_created_today")) { - countToday = await database.query( - getQueryForToday(model.getTableName()), - selectOptions - ); - } - if (requestedReports.includes("total_created_last_year")) { - countLastYear = await database.query( - getQueryForLastYear(model.getTableName()), - selectOptions - ); - } - if (requestedReports.includes("total_created_this_year")) { - countThisYear = await database.query( - getQueryForThisYear(model.getTableName()), - selectOptions - ); - } - if (requestedReports.includes("total_created_this_month")) { - countThisMonth = await database.query( - getQueryForThisMonth(model.getTableName()), - selectOptions - ); - } - if (requestedReports.includes("total_created_this_week")) { - countThisweek = await database.query( - getQueryForThisWeek(model.getTableName()), - selectOptions - ); - } - if (requestedReports.includes("total_created_last_month")) { - countLastMonth = await database.query( - getQueryForLastMonth(model.getTableName()), - selectOptions - ); - } - if (requestedReports.includes("total_created_last_90_days")) { - countLast90Days = await database.query( - getQueryForLast90Days(model.getTableName()), - selectOptions - ); - } - - statsInfo.total_count = get(count, "[0].total_count", 0); - statsInfo.total_created_this_month = get( - countThisMonth, - "[0].total_created_this_month", - 0 - ); - statsInfo.total_created_this_week = get( - countThisweek, - "[0].total_created_this_week", - 0 - ); - statsInfo.total_created_last_7_days = get( - countLast7Days, - "[0].total_created_last_7_days", - 0 - ); - statsInfo.total_created_today = get( - countToday, - "[0].total_created_today", - 0 - ); - statsInfo.total_created_last_month = get( - countLastMonth, - "[0].total_created_last_month", - 0 - ); - statsInfo.total_created_last_90_days = get( - countLast90Days, - "[0].total_created_last_90_days", - 0 - ); - statsInfo.total_created_last_year = get( - countLastYear, - "[0].total_created_last_year", - 0 - ); - statsInfo.total_created_this_year = get( - countThisYear, - "[0].total_created_this_year", - 0 - ); - - resolve(statsInfo); - } catch (error) { - reject(error); - } - }); - }; -} diff --git a/src/framework/database/loadTables.ts b/src/framework/database/loadTables.ts index 495504f8..40ed40fe 100644 --- a/src/framework/database/loadTables.ts +++ b/src/framework/database/loadTables.ts @@ -9,7 +9,6 @@ import { IConfiguration, } from "../types/configuration"; import { applyRelationshipSql } from "../moduleRelationships/database"; -import stats from "./helpers/stats"; import paginate from "./helpers/paginate"; const checkDatabaseOptions = (moduleName, tableName) => { @@ -92,7 +91,6 @@ export default function (connection, configuration: IConfiguration) { }); Object.keys(tables).forEach(async (table) => { - tables[table].stats = await stats(connection, tables[table]); tables[table].paginate = await paginate(tables[table]); }); diff --git a/src/framework/defaults/options/index.ts b/src/framework/defaults/options/index.ts index 18303f82..2422a401 100644 --- a/src/framework/defaults/options/index.ts +++ b/src/framework/defaults/options/index.ts @@ -57,13 +57,7 @@ export const defaultSocketOptions = { }; export const defaultApolloGraphqlOptions = { - cacheControl: { - defaultMaxAge: 0, - }, tracing: true, - subscriptions: { - path: "/subscriptions", - }, }; export const defaultPort = 7000; diff --git a/src/framework/graphql/generalSchema.ts b/src/framework/graphql/generalSchema.ts index 2bffa3d1..e979c960 100644 --- a/src/framework/graphql/generalSchema.ts +++ b/src/framework/graphql/generalSchema.ts @@ -48,17 +48,6 @@ export default ` _ne: Boolean } - type ModuleStats { - total_count: Int - total_created_this_month: Int - total_created_this_week: Int - total_created_last_7_days: Int - total_created_today: Int - total_created_last_month: Int - total_created_last_90_days: Int - total_created_last_year: Int - total_created_this_year: Int - } type Sorting { column: String type: String diff --git a/src/framework/graphql/index.ts b/src/framework/graphql/index.ts index 69386502..68c26705 100644 --- a/src/framework/graphql/index.ts +++ b/src/framework/graphql/index.ts @@ -5,7 +5,7 @@ import { get } from "lodash"; import voyager from "./voyager/index"; import { defaultApolloGraphqlOptions } from "../defaults/options/index"; import GraphQLJSON, { GraphQLJSONObject } from "graphql-type-json"; -const { ApolloServer } = require("apollo-server-express"); +import { ApolloServer } from "apollo-server-express"; import * as auth from "./../helpers/auth"; //expressApp,configuration,models,emailTemplates,sendEmail,database,WertikEventEmitter diff --git a/src/framework/reporting/index.ts b/src/framework/reporting/index.ts deleted file mode 100644 index f4380eb0..00000000 --- a/src/framework/reporting/index.ts +++ /dev/null @@ -1,122 +0,0 @@ -import moment from "moment"; -import { resolve } from "url"; - -export const getYear = (mm = null) => { - return mm ? mm.year() : moment().year(); -}; - -export const getMonth = (mm = null) => { - return mm ? mm.month() + 1 : moment().month() + 1; -}; - -export const getDate = (mm = null) => { - return mm ? mm.date() : moment().date(); -}; - -export const substractDays = (num) => { - return moment().subtract(num, "d"); -}; - -export const getQueryForLast7Days = function (tableName: String) { - return ` - SELECT count(*) as total_created_last_7_days FROM ${tableName} - WHERE DATE(created_at) - BETWEEN - '${getYear(substractDays(7))}-${ - substractDays(7).month() + 1 - }-${substractDays(7).date()}' - AND - '${getYear(substractDays(7))}-${ - moment().month() + 1 - }-${moment().date()}' - `; -}; - -export const getQueryForToday = function (tableName: String) { - return ` - SELECT count(*) as total_created_today FROM ${tableName} - WHERE DATE(created_at) - BETWEEN - '${getYear()}-${getMonth()}-${getDate()} 00:00:00' - AND - '${getYear()}-${getMonth()}-${getDate()} 23:59:59' - `; -}; - -export const getQueryForThisYear = function (tableName: String) { - return ` - SELECT count(*) as total_created_this_year FROM ${tableName} - WHERE DATE(created_at) - BETWEEN - '${getYear()}-1-1' - AND - '${getYear()}-12-31' - `; -}; - -export const getQueryForThisMonth = function (tableName: String) { - return ` - SELECT count(*) as total_created_this_month FROM ${tableName} - WHERE DATE(created_at) - BETWEEN - '${getYear()}-${moment().month() + 1}-${moment().startOf("month").date()}' - AND - '${getYear()}-${moment().month() + 1}-${moment().endOf("month").date()}' - `; -}; - -export const getQueryForThisWeek = function (tableName: String) { - return ` - SELECT count(*) as total_created_this_week FROM ${tableName} - WHERE DATE(created_at) - BETWEEN - '${getYear(moment().startOf("isoWeek"))}-${ - moment().startOf("isoWeek").month() + 1 - }-${moment().startOf("isoWeek").date()}' - AND - '${getYear(moment().endOf("isoWeek"))}-${ - moment().endOf("isoWeek").month() + 1 - }-${moment().endOf("isoWeek").date()}' - `; -}; - -export const getQueryForLastMonth = function (tableName: String) { - return ` - SELECT count(*) as total_created_last_month FROM ${tableName} - WHERE DATE(created_at) - BETWEEN - '${moment().subtract(1, "months").year()}-${ - moment().subtract(1, "months").month() + 1 - }-${moment().subtract(1, "months").startOf("month").date()}' - AND - '${moment().subtract(1, "months").year()}-${ - moment().subtract(1, "months").month() + 1 - }-${moment().subtract(1, "months").endOf("month").date()}' - `; -}; - -export const getQueryForLast90Days = function (tableName: String) { - return ` - SELECT count(*) as total_created_last_90_days FROM ${tableName} - WHERE DATE(created_at) - BETWEEN - '${moment().subtract(90, "days").year()}-${ - moment().subtract(90, "days").month() + 1 - }-${moment().subtract(90, "days").startOf("month").date()}' - AND - '${moment().year()}-${moment().month() + 1}-${moment() - .endOf("month") - .date()}' - `; -}; - -export const getQueryForLastYear = function (tableName: String) { - return ` - SELECT count(*) as total_created_last_year FROM ${tableName} - WHERE DATE(created_at) - BETWEEN - '${getYear() - 1}-1-1' - AND - '${getYear() - 1}-12-31' - `; -}; From 3d0bce46c973c520aa78e8506d7119186b6be2cc Mon Sep 17 00:00:00 2001 From: ilyas Date: Sun, 7 Nov 2021 20:20:10 +0500 Subject: [PATCH 04/23] More Cleanup --- src/framework/database/helpers/index.ts | 8 ---- src/framework/graphql/index.ts | 1 - src/framework/initialization/checkModules.ts | 32 +++++++++------- .../security/getUserAllPermissions.ts | 37 ------------------- src/framework/security/getUserRoles.ts | 18 --------- .../security/getUserWithAccessToken.ts | 21 ----------- src/framework/security/isAccessTokenValid.ts | 0 src/framework/security/isAuthQuery.ts | 23 ------------ src/framework/security/validateAccessToken.ts | 11 ------ 9 files changed, 18 insertions(+), 133 deletions(-) delete mode 100644 src/framework/security/getUserAllPermissions.ts delete mode 100644 src/framework/security/getUserRoles.ts delete mode 100644 src/framework/security/getUserWithAccessToken.ts delete mode 100644 src/framework/security/isAccessTokenValid.ts delete mode 100644 src/framework/security/isAuthQuery.ts delete mode 100644 src/framework/security/validateAccessToken.ts diff --git a/src/framework/database/helpers/index.ts b/src/framework/database/helpers/index.ts index fd7f4ae9..d9884ab3 100644 --- a/src/framework/database/helpers/index.ts +++ b/src/framework/database/helpers/index.ts @@ -12,11 +12,3 @@ export const convertFieldsIntoSequelizeFields = (fields) => { }); return fields; }; - -export const deleteModel = () => {}; - -export const paginateModel = () => {}; - -export const updateModel = () => {}; - -export const viewModel = () => {}; diff --git a/src/framework/graphql/index.ts b/src/framework/graphql/index.ts index 68c26705..1da12abd 100644 --- a/src/framework/graphql/index.ts +++ b/src/framework/graphql/index.ts @@ -1,4 +1,3 @@ -// let { ApolloServer } = require("apollo-server"); import loadAllModules from "./loadAllModules"; import { IGraphQLInitialize } from "./../types/servers"; import { get } from "lodash"; diff --git a/src/framework/initialization/checkModules.ts b/src/framework/initialization/checkModules.ts index f4997980..ed800769 100644 --- a/src/framework/initialization/checkModules.ts +++ b/src/framework/initialization/checkModules.ts @@ -3,21 +3,25 @@ import { IConfiguration } from "../types/configuration"; export default function (configuration: IConfiguration) { const { modules } = configuration; return new Promise((resolve, reject) => { - if (modules.length == 0) { - console.log("[Wertik-js] Starting with no custom modules."); - resolve(true); - } - modules.forEach((element, index) => { - let isLast = index == modules.length - 1; - if (!element || element.constructor !== Object) { - console.error( - `You have passed unsupported modules at index: ${index}, received: ${element.constructor} \n Closing process. Please see: http://www.wapgee.com/wertik-js/getting-started/custom-modules` - ); - process.exit(); - } - if (isLast) { + try { + if (modules.length == 0) { + console.log("[Wertik-js] Starting with no custom modules."); resolve(true); } - }); + modules.forEach((element, index) => { + let isLast = index == modules.length - 1; + if (!element || element.constructor !== Object) { + console.error( + `You have passed unsupported modules at index: ${index}, received: ${element.constructor} \n Closing process. Please see: http://www.wapgee.com/wertik-js/getting-started/custom-modules` + ); + process.exit(); + } + if (isLast) { + resolve(true); + } + }); + } catch (e) { + reject(e); + } }); } diff --git a/src/framework/security/getUserAllPermissions.ts b/src/framework/security/getUserAllPermissions.ts deleted file mode 100644 index bd650c54..00000000 --- a/src/framework/security/getUserAllPermissions.ts +++ /dev/null @@ -1,37 +0,0 @@ -export default async function (userId, database) { - let sqlQuery = ` - SELECT permissionTable.id AS permission_id, - permissionTable.NAME AS permission_name, - permissionTable.can AS permission_can, - permissionTable.cant AS permission_cant, - role_permissionTable.id AS rolepermission_id, - role_permissionTable.role AS rolepermission_role, - role_permissionTable.permission AS rolepermission_permission, - role_permissionTable.NAME AS rolepermission_name, - userpermissionTable.id AS userpermission_id, - userpermissionTable.USER AS userpermission_user, - userpermissionTable.permission AS userpermission_permission, - roleTable.id AS role_id, - roleTable.NAME AS role_name, - userroleTable.id AS userrole_id, - userroleTable.NAME AS userrole_name, - userroleTable.USER AS userrole_user, - userroleTable.role AS userrole_role - FROM permission AS permissionTable - LEFT JOIN role_permission AS role_permissionTable - ON permissionTable.id = role_permissionTable.permission - LEFT JOIN user_permission AS userpermissionTable - ON permissionTable.id = userpermissionTable.permission - LEFT JOIN role AS roleTable - ON role_permissionTable.role = roleTable.id - LEFT JOIN user_role AS userroleTable - ON userroleTable.id = role_permissionTable.role - WHERE userroleTable.USER = _________user_ID - OR userpermissionTable.USER = _________user_ID - `; - sqlQuery = sqlQuery.replace(/_________user_ID/g, userId + ""); - const permissions = await database.query(sqlQuery, { - type: database.QueryTypes.SELECT, - }); - return permissions; -} diff --git a/src/framework/security/getUserRoles.ts b/src/framework/security/getUserRoles.ts deleted file mode 100644 index 80c51071..00000000 --- a/src/framework/security/getUserRoles.ts +++ /dev/null @@ -1,18 +0,0 @@ -export default async function (userId, database) { - let sqlQuery = `SELECT r.*, ur.id as ur_id, - ur.name as ur_name, - ur.created_at as ur_created_at, - ur.updated_at as ur_updated_at, - ur.deleted_at as ur_deleted_at, - ur.role as ur_role, - ur.user as ur_user - - from user_role as ur - left JOIN role as r on r.id = ur.role - where ur.user = _________user_ID`; - sqlQuery = sqlQuery.replace(/_________user_ID/g, userId + ""); - const roles = await database.query(sqlQuery, { - type: database.QueryTypes.SELECT, - }); - return roles; -} diff --git a/src/framework/security/getUserWithAccessToken.ts b/src/framework/security/getUserWithAccessToken.ts deleted file mode 100644 index 8ee0021d..00000000 --- a/src/framework/security/getUserWithAccessToken.ts +++ /dev/null @@ -1,21 +0,0 @@ -let { get } = require("lodash"); -export default async function (UserModel: any, token: string) { - try { - let find = await UserModel.findOne({ - where: { - access_token: token, - }, - include: "*", - }); - return get(find, "instance", null); - } catch (errorInstance) { - let modules: any = process.env.builtinModules; - modules = modules.split(","); - modules = modules.filter((c) => c); - if (modules.length == 0) { - return null; - } else { - throw errorInstance; - } - } -} diff --git a/src/framework/security/isAccessTokenValid.ts b/src/framework/security/isAccessTokenValid.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/src/framework/security/isAuthQuery.ts b/src/framework/security/isAuthQuery.ts deleted file mode 100644 index 8f8c93f3..00000000 --- a/src/framework/security/isAuthQuery.ts +++ /dev/null @@ -1,23 +0,0 @@ -let { get } = require("lodash"); -let gql = require("graphql-tag"); -export default function (query: string) { - let parsed = gql` - ${query} - `; - let queryName = get( - parsed, - "definitions[0].selectionSet.selections[0].name.value", - "" - ); - let auth = [ - "signup", - "resetPassword", - "requestPasswordResetToken", - "login", - "activateAccount", - "generalAccessToken", - "twoFactorLogin", - "twoFactorLoginValidate", - ]; - return auth.indexOf(queryName) > -1; -} diff --git a/src/framework/security/validateAccessToken.ts b/src/framework/security/validateAccessToken.ts deleted file mode 100644 index b6639c8e..00000000 --- a/src/framework/security/validateAccessToken.ts +++ /dev/null @@ -1,11 +0,0 @@ -import getUserWithAccessToken from "./getUserWithAccessToken"; - -export default async function (userModel, accessToken) { - const token = accessToken.replace("bearer ", ""); - const user = await getUserWithAccessToken(userModel, token); - if (user) { - return user; - } else { - throw new Error("Access token expired"); - } -} From 385eb3777f1c28fbd386fd5666342fae6c77c345 Mon Sep 17 00:00:00 2001 From: ilyas Date: Sun, 7 Nov 2021 22:44:19 +0500 Subject: [PATCH 05/23] Cleanup --- src/framework/defaults/options/index.ts | 4 +--- src/framework/helpers/replaceFilterOperators.ts | 4 ++-- src/framework/helpers/validateConfigurationObject.ts | 8 +++----- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/framework/defaults/options/index.ts b/src/framework/defaults/options/index.ts index 2422a401..22466113 100644 --- a/src/framework/defaults/options/index.ts +++ b/src/framework/defaults/options/index.ts @@ -56,8 +56,6 @@ export const defaultSocketOptions = { }, }; -export const defaultApolloGraphqlOptions = { - tracing: true, -}; +export const defaultApolloGraphqlOptions = {}; export const defaultPort = 7000; diff --git a/src/framework/helpers/replaceFilterOperators.ts b/src/framework/helpers/replaceFilterOperators.ts index 2e38645c..92ca8b13 100644 --- a/src/framework/helpers/replaceFilterOperators.ts +++ b/src/framework/helpers/replaceFilterOperators.ts @@ -11,11 +11,11 @@ const iterate = (obj) => { const isArray = Array.isArray(obj); if (isObject) { const keys = Object.keys(obj); - keys.forEach((element) => { + keys.forEach((element: string) => { const value = obj[element]; const isArray = Array.isArray(value); const isObject = isPlainObject(value); - if (element.indexOf("_") === 0) { + if (element.startsWith("_")) { const newWrapValue = wrap(element); obj[newWrapValue] = obj[element]; delete obj[element]; diff --git a/src/framework/helpers/validateConfigurationObject.ts b/src/framework/helpers/validateConfigurationObject.ts index 483fa308..4715baa5 100644 --- a/src/framework/helpers/validateConfigurationObject.ts +++ b/src/framework/helpers/validateConfigurationObject.ts @@ -14,11 +14,9 @@ export const requiredFields = { export default function (configuration) { return new Promise(async (resolve, reject) => { try { - let responseCheckInstalledPackages = await checkInstalledPackages( - configuration - ); - let responseCheckModules = await checkModules(configuration); - resolve(); + await checkInstalledPackages(configuration); + await checkModules(configuration); + resolve(true); } catch (errr) { reject(errr); console.log(errr); From 46e520b81a379ca101ce4373b383e7f696deba8f Mon Sep 17 00:00:00 2001 From: ilyas Date: Sun, 7 Nov 2021 22:49:20 +0500 Subject: [PATCH 06/23] Apollo Build Error --- tsconfig.json | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index 193dc844..59ac1313 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,19 +1,16 @@ { - "compilerOptions": { - "module": "commonjs", - "esModuleInterop": true, - "target": "es2015", - "noImplicitAny": false, - "moduleResolution": "node", - "sourceMap": true, - "outDir": "lib", - "baseUrl": "./", - "lib": ["es6", "esnext.asynciterable"], - "types": [ - "node" - ] - }, - "include": [ - "src/**/*" - ] -} \ No newline at end of file + "compilerOptions": { + "module": "commonjs", + "esModuleInterop": true, + "target": "es2015", + "noImplicitAny": false, + "moduleResolution": "node", + "sourceMap": true, + "outDir": "lib", + "baseUrl": "./", + "lib": ["es6", "esnext.asynciterable"], + "types": ["node"], + "skipLibCheck": true + }, + "include": ["src/**/*"] +} From 80c658256492295dc2799c7e322b38bf845a5862 Mon Sep 17 00:00:00 2001 From: ilyas Date: Wed, 10 Nov 2021 07:07:49 +0500 Subject: [PATCH 07/23] Allowing types --- package.json | 1 + src/next/devServer.ts | 11 +++++++++-- src/next/sockets/index.ts | 20 +++++++++++++++----- src/next/types/types.ts | 23 ++++++++++++++++++++++- tsconfig.json | 3 ++- 5 files changed, 49 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 63db8be8..fd8a5bea 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "wertik-js", "version": "3.0.8-beta", "main": "lib/main.js", + "types": "lib/types.d.ts", "repository": "https://github.com/Uconnect-Technologies/wertik-js.git", "keywords": [ "mysql", diff --git a/src/next/devServer.ts b/src/next/devServer.ts index 1e76683d..42feee08 100644 --- a/src/next/devServer.ts +++ b/src/next/devServer.ts @@ -1,6 +1,7 @@ import { useDatabase } from "./database"; import { useGraphql } from "./graphql"; -import wertik, { useModule } from "./index"; +import wertik, { useModule, useWebSockets } from "./index"; +import { useIndependentWebSocketsServer, useSocketIO } from "./sockets"; (async () => { wertik({ @@ -9,7 +10,13 @@ import wertik, { useModule } from "./index"; cronJobs: {}, email: {}, storage: {}, - sockets: {}, + sockets: { + ws: useWebSockets({}), + wsi: useIndependentWebSocketsServer({ + port: 1300, + }), + sio: useSocketIO({}), + }, database: {}, modules: {}, }); diff --git a/src/next/sockets/index.ts b/src/next/sockets/index.ts index d8f67d0f..04972a96 100644 --- a/src/next/sockets/index.ts +++ b/src/next/sockets/index.ts @@ -1,8 +1,11 @@ import { isFunction } from "lodash"; import { Server } from "socket.io"; -import { Server as WebSocketServer } from "ws"; +import { + Server as WebSocketServer, + ServerOptions as WebSocketServerOptions, +} from "ws"; -export const useWebSockets = (configuration) => { +export const useWebSockets = (configuration: WebSocketServerOptions = {}) => { return (props, app) => { return new WebSocketServer({ server: app.server, @@ -11,15 +14,20 @@ export const useWebSockets = (configuration) => { }; }; -export const useIndependentWebSocketsServer = (configuration) => { +export const useIndependentWebSocketsServer = ( + configuration: WebSocketServerOptions = {} +) => { return (props, app) => { + console.log( + `[Wertik JS] Web Sockets server starting at ws://localhost:${configuration.port}` + ); return new WebSocketServer({ ...configuration, }); }; }; -export const useSocketIO = (configuration) => { +export const useSocketIO = (configuration = {}) => { return (props) => { return new Server(props.server, { ...configuration, @@ -30,6 +38,8 @@ export const useSocketIO = (configuration) => { export default function (props, app) { Object.keys(props.sockets).forEach((element) => { const socket = props.sockets[element]; - if (isFunction(socket)) socket(props, app); + if (isFunction(socket)) { + socket(props, app); + } }); } diff --git a/src/next/types/types.ts b/src/next/types/types.ts index 5bfa8b4e..cc2b8380 100644 --- a/src/next/types/types.ts +++ b/src/next/types/types.ts @@ -2,6 +2,28 @@ import { Express } from "express"; import { Http2Server } from "http2"; import { Sequelize } from "sequelize/types"; +export interface NextConfigurationProps { + port: number; + skip: any; + express: any; + database: { + [key: string]: { + name: string; + username: string; + password: string; + host: number; + options: { + [key: string]: any; + }; + }; + }; + modules: any; + cronJobs: any; + sockets: any; + graphql: any; + [Key: string]: any; +} + export interface WertikApp { express?: Express; server?: Http2Server; @@ -30,7 +52,6 @@ export interface WertikDatabaseCredentials { name: string; } export interface WertikStorage {} - export interface useGraphqlProps {} export interface useCronJobsProps {} export interface useMailerProps {} diff --git a/tsconfig.json b/tsconfig.json index 59ac1313..d7a4c2d8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,7 +10,8 @@ "baseUrl": "./", "lib": ["es6", "esnext.asynciterable"], "types": ["node"], - "skipLibCheck": true + "skipLibCheck": true, + "declaration": true }, "include": ["src/**/*"] } From 1a67c692b456f7ebdc82b0cfc61db0ff8a32dd57 Mon Sep 17 00:00:00 2001 From: ilyas Date: Wed, 10 Nov 2021 08:14:28 +0500 Subject: [PATCH 08/23] Fix Socket issues --- src/next/devServer.ts | 8 +------- src/next/sockets/index.ts | 23 ++++++++++++++++------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/next/devServer.ts b/src/next/devServer.ts index 42feee08..31051bf7 100644 --- a/src/next/devServer.ts +++ b/src/next/devServer.ts @@ -10,13 +10,7 @@ import { useIndependentWebSocketsServer, useSocketIO } from "./sockets"; cronJobs: {}, email: {}, storage: {}, - sockets: { - ws: useWebSockets({}), - wsi: useIndependentWebSocketsServer({ - port: 1300, - }), - sio: useSocketIO({}), - }, + sockets: {}, database: {}, modules: {}, }); diff --git a/src/next/sockets/index.ts b/src/next/sockets/index.ts index 04972a96..a315b75d 100644 --- a/src/next/sockets/index.ts +++ b/src/next/sockets/index.ts @@ -1,5 +1,5 @@ import { isFunction } from "lodash"; -import { Server } from "socket.io"; +import { Server as SocketIOServer } from "socket.io"; import { Server as WebSocketServer, ServerOptions as WebSocketServerOptions, @@ -7,6 +7,12 @@ import { export const useWebSockets = (configuration: WebSocketServerOptions = {}) => { return (props, app) => { + if (!configuration.path) { + throw new Error("Path must be passed for useWebSockets"); + } + console.log( + `Web Sockets server starting at ws://localhost:${props.port}${configuration.path}` + ); return new WebSocketServer({ server: app.server, ...configuration, @@ -19,7 +25,7 @@ export const useIndependentWebSocketsServer = ( ) => { return (props, app) => { console.log( - `[Wertik JS] Web Sockets server starting at ws://localhost:${configuration.port}` + `Web Sockets server starting at ws://localhost:${configuration.port}${configuration.path}` ); return new WebSocketServer({ ...configuration, @@ -27,11 +33,14 @@ export const useIndependentWebSocketsServer = ( }; }; -export const useSocketIO = (configuration = {}) => { - return (props) => { - return new Server(props.server, { - ...configuration, - }); +export const useSocketIO = (configuration: any = {}) => { + return (props, app) => { + console.log( + `Socket.IO server starting at http://localhost:${props.port}${ + configuration.path ?? "/socket.io" + }` + ); + return new SocketIOServer(app.server, configuration); }; }; From 0abcc8aa1766e536adc700fab32517b5c7ae42da Mon Sep 17 00:00:00 2001 From: ilyas Date: Thu, 11 Nov 2021 12:48:33 +0500 Subject: [PATCH 09/23] new types --- src/next/database.ts | 44 ++++++------ src/next/devServer.ts | 35 ++++++++-- src/next/graphql/index.ts | 3 +- src/next/index.ts | 49 ++++++------- src/next/mailer/index.ts | 107 ++++++++++++++--------------- src/next/modules/modules.ts | 6 +- src/next/sockets/index.ts | 4 +- src/next/storage/index.ts | 8 +-- src/next/types/types.ts | 58 ++++++++++------ src/next/types/types.v2.ts | 133 ++++++++++++++++++++++++++++++++++++ 10 files changed, 306 insertions(+), 141 deletions(-) create mode 100644 src/next/types/types.v2.ts diff --git a/src/next/database.ts b/src/next/database.ts index 9a90b302..99b12c2a 100644 --- a/src/next/database.ts +++ b/src/next/database.ts @@ -2,6 +2,7 @@ import { Sequelize } from "sequelize"; import { databaseDefaultOptions } from "../framework/defaults/options"; import { get } from "lodash"; import { paginate } from "./crud/index"; +import { UseDatabaseProps } from "./types/types.v2"; export const getAllRelationships = (dbName: String) => { return ` @@ -14,30 +15,27 @@ export const getAllRelationships = (dbName: String) => { `; }; -export const useDatabase = function (obj: any) { - return () => - new Promise(async (resolve, reject) => { - let sequelize = new Sequelize(obj.name, obj.username, obj.password, { - host: obj.host, - dialect: "mysql", - logging: false, - ...get(obj, "options", {}), - ...(databaseDefaultOptions as any).sql.dbInitializeOptions, - }); - try { - await sequelize.authenticate(); - (sequelize as any).relationships = await sequelize.query( - getAllRelationships(obj.name) - ); - console.log(`[DB] Succcessfully connected to database ${obj.name}`); - resolve({ - credentials: obj, - instance: sequelize, - }); - } catch (e) { - reject(`${e.message} \n [DB] Error connecting to database ${obj.name}`); - } +export const useDatabase = function (obj: UseDatabaseProps) { + return async () => { + let sequelize = new Sequelize(obj.name, obj.username, obj.password, { + host: obj.host, + dialect: "mysql", + logging: false, + ...get(obj, "options", {}), + ...(databaseDefaultOptions as any).sql.dbInitializeOptions, }); + await sequelize.authenticate().catch((err) => { + throw new Error(err); + }); + (sequelize as any).relationships = await sequelize.query( + getAllRelationships(obj.name) + ); + console.log(`[DB] Succcessfully connected to database ${obj.name}`); + return { + credentials: obj, + instance: sequelize, + }; + }; }; export const applyRelationshipsFromStoreToDatabase = async (store, app) => { diff --git a/src/next/devServer.ts b/src/next/devServer.ts index 31051bf7..d765f535 100644 --- a/src/next/devServer.ts +++ b/src/next/devServer.ts @@ -1,17 +1,38 @@ import { useDatabase } from "./database"; import { useGraphql } from "./graphql"; import wertik, { useModule, useWebSockets } from "./index"; +import { useMailer } from "./mailer"; import { useIndependentWebSocketsServer, useSocketIO } from "./sockets"; (async () => { wertik({ port: 1200, - graphql: useGraphql(), - cronJobs: {}, - email: {}, - storage: {}, - sockets: {}, - database: {}, - modules: {}, + database: { + jscontainer: useDatabase({ + name: "jscontainer", + password: "pass", + host: "localhost", + port: 3306, + username: "root", + }), + }, + mailer: { + mail: useMailer(), + }, + modules: { + containers: useModule({ + table: "containers", + database: "jscontainer", + name: "containers", + useDatabase: true, + }), + }, + // graphql: useGraphql(), + // cronJobs: {}, + // email: {}, + // storage: {}, + // sockets: {}, + // database: {}, + // modules: {}, }); })(); diff --git a/src/next/graphql/index.ts b/src/next/graphql/index.ts index 9de85cb9..94caf5d1 100644 --- a/src/next/graphql/index.ts +++ b/src/next/graphql/index.ts @@ -1,8 +1,9 @@ import { get, omit } from "lodash"; import { defaultApolloGraphqlOptions } from "../../framework/defaults/options"; import { ApolloServer } from "apollo-server-express"; +import { useGraphqlProps, WertikConfiguration } from "../types/types.v2"; -export const useGraphql = (obj = {}) => obj; +export const useGraphql = (obj) => ApolloServer; export default function ({ wertikApp, app, store, configuration }) { store.graphql.typeDefs = store.graphql.typeDefs.concat( diff --git a/src/next/index.ts b/src/next/index.ts index c850b852..7098f025 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -11,6 +11,8 @@ import cronJobs from "./cronJobs"; import storage from "./storage/index"; import sockets from "./sockets"; import http from "http"; +import { WertikConfiguration } from "./types/types.v2"; +import { WertikApp } from "./types/types.v2"; export * from "./database"; export * from "./modules/modules"; @@ -21,37 +23,29 @@ export * from "./storage"; export * from "./helpers/modules/backup"; export * from "./sockets"; -export default async function (configuration: any = {}) { +export default async function (configuration: WertikConfiguration) { return new Promise(async (resolve, reject) => { try { - const wertikApp: { [key: string]: any } = { - email: { - sendEmail: () => {}, - }, + const wertikApp: WertikApp = { modules: {}, - cronJobs: {}, - storage: {}, database: {}, + mailer: {}, }; const port = get(configuration, "port", 5050); const skip = get(configuration, "skip", false); const app = get(configuration, "express", express()); - const server = http.createServer(app); + const httpServer = http.createServer(app); - wertikApp.server = server; + wertikApp.httpServer = httpServer; wertikApp.express = app; - wertikApp.email = { - sendEmail: emailSender(configuration), - ...get(configuration, "email", {}), - }; if (configuration.database) { for (const databaseName of Object.keys(configuration.database)) { try { - configuration.database[databaseName] = wertikApp.database[ + wertikApp.database[databaseName] = await configuration.database[ databaseName - ] = await configuration.database[databaseName](); + ](); } catch (e) { throw new Error(e); } @@ -60,12 +54,13 @@ export default async function (configuration: any = {}) { if (configuration.modules) { for (const moduleName of Object.keys(configuration.modules)) { - configuration.modules[moduleName] = wertikApp.modules[moduleName] = - await configuration.modules[moduleName]( - configuration, - store, - wertikApp - ); + wertikApp.modules[moduleName] = await configuration.modules[ + moduleName + ]({ + store: store, + configuration: configuration, + app: wertikApp, + }); } } @@ -84,7 +79,7 @@ export default async function (configuration: any = {}) { configuration.sockets && sockets(configuration, wertikApp); if (configuration.graphql) { - configuration.graphql = wertikApp.graphql = graphql({ + wertikApp.graphql = graphql({ wertikApp, app, store, @@ -92,6 +87,12 @@ export default async function (configuration: any = {}) { }); } + for (const mailName of Object.keys(configuration.mailer)) { + wertikApp.mailer[mailName] = configuration.mailer[mailName]; + } + + wertikApp.sendEmail = emailSender(wertikApp); + app.use(async function (req, res, next) { req.wertik = wertikApp; next(); @@ -99,11 +100,11 @@ export default async function (configuration: any = {}) { setTimeout(async () => { if (skip === false) { - server.listen(port, () => { + httpServer.listen(port, () => { console.log(`Wertik JS app listening at http://localhost:${port}`); }); } - resolve(app); + resolve(wertikApp); }, 500); } catch (e) { console.error(e); diff --git a/src/next/mailer/index.ts b/src/next/mailer/index.ts index 635f6189..275fc2b2 100644 --- a/src/next/mailer/index.ts +++ b/src/next/mailer/index.ts @@ -1,66 +1,61 @@ import nodemailer from "nodemailer"; import handlebars from "handlebars"; +import { emailSendProps, iObject, WertikApp } from "../types/types.v2"; -export const useMailer = async () => { - return new Promise(async (resolve, reject) => { - try { - let testAccount = await nodemailer.createTestAccount(); - const wertiknodemailerDefaultConfiguration = { - host: "smtp.ethereal.email", - port: 587, - secure: false, - auth: { - user: testAccount.user, - pass: testAccount.pass, - }, - }; - let transporter = nodemailer.createTransport( - wertiknodemailerDefaultConfiguration - ); - resolve(transporter); - } catch (e) { - console.log( - `Something went wrong while setting up email system: ${e.message}` - ); - reject(e); - } - }); +export const useMailer = (props?: iObject) => { + return async () => { + let testAccount = await nodemailer.createTestAccount(); + + const wertiknodemailerDefaultConfiguration = props + ? props + : { + host: "smtp.ethereal.email", + port: 587, + secure: false, + auth: { + user: testAccount.user, + pass: testAccount.pass, + }, + }; + + let transporter = nodemailer.createTransport( + wertiknodemailerDefaultConfiguration + ); + + return transporter; + }; }; -export const emailSender = (app) => { - return (mailer, options) => { - return new Promise(async (resolve, reject) => { - try { - let transporter = app.email[mailer]; +export const emailSender = (app: WertikApp) => { + const fn = (props: { mailer: string; options: emailSendProps }) => { + return async () => { + let transporter = app.mailer[props.mailer]; - if (!transporter) { - throw new Error( - `Email integration ${mailer} not found. Please check the typo.` - ); - } + if (!transporter) { + throw new Error( + `Email integration ${props.mailer} not found. Please check the typo.` + ); + } - let compiled = handlebars.compile(options.template); - let resultTemplate = compiled(options.variables); - let emailInstance = await transporter.sendMail({ - from: options.from, - to: options.to, - html: resultTemplate, - subject: options.subject, - }); - if (emailInstance && emailInstance.messageId) { - console.log("Message sent: %s", emailInstance.messageId); - } - if (nodemailer && nodemailer.getTestMessageUrl) { - console.log( - "Preview URL: %s", - nodemailer.getTestMessageUrl(emailInstance) - ); - } - resolve(true); - } catch (e) { - console.error(e); - reject(e); + let compiled = handlebars.compile(props.options.template); + let resultTemplate = compiled(props.options.variables); + let emailInstance = await transporter.sendMail({ + from: props.options.from, + to: props.options.to, + html: resultTemplate, + subject: props.options.subject, + }); + if (emailInstance && emailInstance.messageId) { + console.log("Message sent: %s", emailInstance.messageId); + } + if (nodemailer && nodemailer.getTestMessageUrl) { + console.log( + "Preview URL: %s", + nodemailer.getTestMessageUrl(emailInstance) + ); } - }); + return emailInstance; + }; }; + return fn; }; diff --git a/src/next/modules/modules.ts b/src/next/modules/modules.ts index 06e83126..cf49cd93 100644 --- a/src/next/modules/modules.ts +++ b/src/next/modules/modules.ts @@ -107,7 +107,7 @@ const getCreateSchema = (props, tableInformation) => { }; export const useModule = (props: useModuleProps) => { - return async (wertik: any, store: any, wertikApp: any) => { + return async ({ store, configuration, app }: any) => { let tableInstance; let graphqlSchema = []; @@ -139,7 +139,7 @@ export const useModule = (props: useModuleProps) => { const useExpress = (fn = (express) => {}) => { setTimeout(() => { - fn(wertikApp.express); + fn(app.express); }, 2500); }; @@ -148,7 +148,7 @@ export const useModule = (props: useModuleProps) => { if (useDatabase) { var createSchema = []; var updateSchema = []; - const connection = wertik.database[props.database]; + const connection = app.database[props.database]; const describe = await connection.instance.query( `describe ${props.table}` ); diff --git a/src/next/sockets/index.ts b/src/next/sockets/index.ts index a315b75d..dc2d5e03 100644 --- a/src/next/sockets/index.ts +++ b/src/next/sockets/index.ts @@ -14,7 +14,7 @@ export const useWebSockets = (configuration: WebSocketServerOptions = {}) => { `Web Sockets server starting at ws://localhost:${props.port}${configuration.path}` ); return new WebSocketServer({ - server: app.server, + server: app.httpServer, ...configuration, }); }; @@ -40,7 +40,7 @@ export const useSocketIO = (configuration: any = {}) => { configuration.path ?? "/socket.io" }` ); - return new SocketIOServer(app.server, configuration); + return new SocketIOServer(app.httpServer, configuration); }; }; diff --git a/src/next/storage/index.ts b/src/next/storage/index.ts index d024bc29..bd27b093 100644 --- a/src/next/storage/index.ts +++ b/src/next/storage/index.ts @@ -1,14 +1,14 @@ -export const useStorage = (obj) => obj; - const DIGITAL_OCEAN = "digitalocean"; const DROPBOX = "dropbox"; +export const useStorage = (obj) => obj; + export default function (props, wertikApp) { Object.keys(props.storage).forEach((element) => { const storageItem = props.storage[element]; if (storageItem.for === DIGITAL_OCEAN) { - const digitalOceanSpacesDetails = storageItem.options; + const digitalOceanSpacesDetails = storageItem.digitalOceanOptions; const aws = require("aws-sdk"); @@ -30,7 +30,7 @@ export default function (props, wertikApp) { s3, }; } else if (storageItem.for === DROPBOX) { - const dropdboxDetails = storageItem.options; + const dropdboxDetails = storageItem.dropboxOptions; const { Dropbox } = require("dropbox"); const dropboxInstance = new Dropbox({ accessToken: dropdboxDetails.accessToken, diff --git a/src/next/types/types.ts b/src/next/types/types.ts index cc2b8380..36ecef78 100644 --- a/src/next/types/types.ts +++ b/src/next/types/types.ts @@ -3,31 +3,30 @@ import { Http2Server } from "http2"; import { Sequelize } from "sequelize/types"; export interface NextConfigurationProps { - port: number; - skip: any; - express: any; - database: { - [key: string]: { - name: string; - username: string; - password: string; - host: number; - options: { - [key: string]: any; - }; - }; + port?: number; + skip?: any; + express?: any; + database?: { + [key: string]: (props: useDatabaseProps) => Function; + }; + modules?: { + [key: string]: (props: useModuleProps) => Function; + }; + cronJobs?: any; + sockets?: { + [key: string]: (props: any) => Function; }; - modules: any; - cronJobs: any; - sockets: any; - graphql: any; - [Key: string]: any; + graphql?: (props: useGraphqlProps) => { [key: string]: any }; + email?: { + [key: string]: (props: useMailerProps) => Function; + }; + storage?: any; } export interface WertikApp { express?: Express; server?: Http2Server; - port: number | string; + port?: number | string; skip: boolean; email: {}; database: { @@ -52,13 +51,30 @@ export interface WertikDatabaseCredentials { name: string; } export interface WertikStorage {} -export interface useGraphqlProps {} +export interface useGraphqlProps { + options?: { + [key: string]: any; + }; + resolvers?: { + Mutation: {}; + Query: {}; + }; + typeDefs?: string; +} export interface useCronJobsProps {} export interface useMailerProps {} export interface useIndependentWebSocketsServerProps {} export interface useWebSocketsProps {} export interface useSocketIOProps {} -export interface useDatabaseProps {} +export interface useDatabaseProps { + name: string; + username: string; + password: string; + host: number; + options: { + [key: string]: any; + }; +} export interface useModuleProps { name: string; diff --git a/src/next/types/types.v2.ts b/src/next/types/types.v2.ts new file mode 100644 index 00000000..64c99f46 --- /dev/null +++ b/src/next/types/types.v2.ts @@ -0,0 +1,133 @@ +import { ApolloServer } from "apollo-server-express"; +import { Sequelize } from "sequelize/types"; +import { useDatabaseProps, WertikDatabase } from "./types"; + +export type iObject = { [key: string]: any }; + +export interface ModuleProps { + name: string; + useDatabase: false; + table: string; + database: string; +} + +export interface Store { + graphql: { + typeDefs: String; + resolvers: { + Query: { + [key: string]: Function; + }; + Mutation: { + [key: string]: Function; + }; + }; + }; + database: { + relationships: Array; + }; +} + +export interface useStorageProps { + for: "dropbox" | "digitalocean"; + dropboxOptions?: { + accessToken: string; + }; + digitalOceanOptions?: { + accessKeyId: string; + secretAccessKey: string; + spacesEndpoint: string; + }; +} + +export interface UseDatabaseProps { + name: string; + username: string; + password: string; + host: string; + port: number; + options?: iObject; +} + +export interface WertikConfiguration { + port: number; + express?: any; + httpServer?: iObject; + skip?: boolean; + database?: { + [key: string]: () => Promise<{ + credentials: UseDatabaseProps; + instance: Sequelize; + }>; + }; + modules?: { + [key: string]: ({ + store: Store, + configuration: WertikConfiguration, + app: WertikApp, + }) => iObject; + }; + storage?: { + [key: string]: (props: useStorageProps) => ({ + configuration: WertikConfiguration, + app: WertikApp, + }) => { + spacesEndpoint?: iObject; + s3?: iObject; + dropbox?: iObject; + }; + }; + mailer?: { + [key: string]: () => Promise; + }; + sockets?: { + [key: string]: () => ({ + configuration: WertikConfiguration, + app: WertikApp, + }) => iObject; + }; + graphql?: ({ + store: Store, + wertikApp: WertikApp, + configuration: WertikConfiguration, + }) => iObject; + cronJobs?: (prop: useCronJobsProps) => () => iObject; +} + +export interface useCronJobsProps { + expression: string; + beforeRun: (app: WertikApp) => void | any; + afterRun: (app: WertikApp) => void | any; + handler: (app: WertikApp) => void | any; +} + +export interface emailSendProps { + template: string; + variables: { + [key: string]: any; + }; + from: string; + to: string; + subject: string; + [key: string]: any; +} + +export interface useGraphqlProps { + options?: { + [key: string]: any; + }; + resolvers?: { + Mutation: {}; + Query: {}; + }; + typeDefs?: string; +} + +export interface userMailerProps {} + +export interface WertikApp { + sendEmail?: ( + app: WertikApp + ) => ({ mailer: string, options: emailSendProps }) => iObject; + [key: string]: any; +} From 14ba656e97c0284f5a7643405d192833e1e539ce Mon Sep 17 00:00:00 2001 From: ilyas Date: Fri, 12 Nov 2021 04:48:27 +0500 Subject: [PATCH 10/23] Adding types --- src/next/devServer.ts | 13 +++---------- src/next/graphql/index.ts | 21 +++++++++++++++------ src/next/index.ts | 14 +++++++------- src/next/types/types.v2.ts | 7 +++++++ 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/next/devServer.ts b/src/next/devServer.ts index d765f535..a00f4776 100644 --- a/src/next/devServer.ts +++ b/src/next/devServer.ts @@ -1,12 +1,12 @@ import { useDatabase } from "./database"; import { useGraphql } from "./graphql"; -import wertik, { useModule, useWebSockets } from "./index"; -import { useMailer } from "./mailer"; -import { useIndependentWebSocketsServer, useSocketIO } from "./sockets"; +import wertik from "./index"; +import { useMailer, useModule, useWebSockets } from "./index"; (async () => { wertik({ port: 1200, + graphql: useGraphql(), database: { jscontainer: useDatabase({ name: "jscontainer", @@ -27,12 +27,5 @@ import { useIndependentWebSocketsServer, useSocketIO } from "./sockets"; useDatabase: true, }), }, - // graphql: useGraphql(), - // cronJobs: {}, - // email: {}, - // storage: {}, - // sockets: {}, - // database: {}, - // modules: {}, }); })(); diff --git a/src/next/graphql/index.ts b/src/next/graphql/index.ts index 94caf5d1..074f32a1 100644 --- a/src/next/graphql/index.ts +++ b/src/next/graphql/index.ts @@ -1,11 +1,20 @@ import { get, omit } from "lodash"; import { defaultApolloGraphqlOptions } from "../../framework/defaults/options"; import { ApolloServer } from "apollo-server-express"; -import { useGraphqlProps, WertikConfiguration } from "../types/types.v2"; - -export const useGraphql = (obj) => ApolloServer; - -export default function ({ wertikApp, app, store, configuration }) { +import { + GraphqlInitializeProps, + iObject, + useGraphqlProps, +} from "../types/types.v2"; + +export const useGraphql = (obj?) => obj; + +export default function ({ + wertikApp, + expressApp, + store, + configuration, +}: GraphqlInitializeProps) { store.graphql.typeDefs = store.graphql.typeDefs.concat( get(configuration, "graphql.typeDefs", "") ); @@ -39,7 +48,7 @@ export default function ({ wertikApp, app, store, configuration }) { }, }); - GraphqlApolloServer.applyMiddleware({ app }); + GraphqlApolloServer.applyMiddleware({ app: expressApp }); return GraphqlApolloServer; } diff --git a/src/next/index.ts b/src/next/index.ts index 7098f025..fb2ed84f 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -78,21 +78,21 @@ export default async function (configuration: WertikConfiguration) { configuration.storage && storage(configuration, wertikApp); configuration.sockets && sockets(configuration, wertikApp); + for (const mailName of Object.keys(configuration.mailer)) { + wertikApp.mailer[mailName] = configuration.mailer[mailName]; + } + + wertikApp.sendEmail = emailSender(wertikApp); + if (configuration.graphql) { wertikApp.graphql = graphql({ wertikApp, - app, + expressApp: app, store, configuration, }); } - for (const mailName of Object.keys(configuration.mailer)) { - wertikApp.mailer[mailName] = configuration.mailer[mailName]; - } - - wertikApp.sendEmail = emailSender(wertikApp); - app.use(async function (req, res, next) { req.wertik = wertikApp; next(); diff --git a/src/next/types/types.v2.ts b/src/next/types/types.v2.ts index 64c99f46..dc4556c0 100644 --- a/src/next/types/types.v2.ts +++ b/src/next/types/types.v2.ts @@ -131,3 +131,10 @@ export interface WertikApp { ) => ({ mailer: string, options: emailSendProps }) => iObject; [key: string]: any; } + +export interface GraphqlInitializeProps { + wertikApp: WertikApp; + store: Store; + configuration: WertikConfiguration; + expressApp: any; +} From 2faddbf1b1f6991cec48e4b5fe0e24bd86916ced Mon Sep 17 00:00:00 2001 From: ilyas Date: Fri, 12 Nov 2021 06:47:40 +0500 Subject: [PATCH 11/23] changed ordering --- src/next/graphql/index.ts | 8 ++------ src/next/index.ts | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/next/graphql/index.ts b/src/next/graphql/index.ts index 074f32a1..21f85ee3 100644 --- a/src/next/graphql/index.ts +++ b/src/next/graphql/index.ts @@ -1,13 +1,9 @@ import { get, omit } from "lodash"; import { defaultApolloGraphqlOptions } from "../../framework/defaults/options"; import { ApolloServer } from "apollo-server-express"; -import { - GraphqlInitializeProps, - iObject, - useGraphqlProps, -} from "../types/types.v2"; +import { GraphqlInitializeProps } from "../types/types.v2"; -export const useGraphql = (obj?) => obj; +export const useGraphql = (obj?) => obj ?? {}; export default function ({ wertikApp, diff --git a/src/next/index.ts b/src/next/index.ts index fb2ed84f..c28023a2 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -40,6 +40,14 @@ export default async function (configuration: WertikConfiguration) { wertikApp.httpServer = httpServer; wertikApp.express = app; + for (const mailName of Object.keys(configuration.mailer)) { + wertikApp.mailer[mailName] = configuration.mailer[mailName]; + } + + configuration.cronJobs && cronJobs(configuration, wertikApp); + configuration.storage && storage(configuration, wertikApp); + configuration.sockets && sockets(configuration, wertikApp); + if (configuration.database) { for (const databaseName of Object.keys(configuration.database)) { try { @@ -52,6 +60,9 @@ export default async function (configuration: WertikConfiguration) { } } + applyRelationshipsFromStoreToDatabase(store, wertikApp); + applyRelationshipsFromStoreToGraphql(store, wertikApp); + if (configuration.modules) { for (const moduleName of Object.keys(configuration.modules)) { wertikApp.modules[moduleName] = await configuration.modules[ @@ -64,9 +75,6 @@ export default async function (configuration: WertikConfiguration) { } } - applyRelationshipsFromStoreToDatabase(store, wertikApp); - applyRelationshipsFromStoreToGraphql(store, wertikApp); - app.get("/w/info", function (req, res) { res.json({ message: "You are running wertik-js", @@ -74,14 +82,6 @@ export default async function (configuration: WertikConfiguration) { }); }); - configuration.cronJobs && cronJobs(configuration, wertikApp); - configuration.storage && storage(configuration, wertikApp); - configuration.sockets && sockets(configuration, wertikApp); - - for (const mailName of Object.keys(configuration.mailer)) { - wertikApp.mailer[mailName] = configuration.mailer[mailName]; - } - wertikApp.sendEmail = emailSender(wertikApp); if (configuration.graphql) { From 2c34788c5782101ce3f75c85a7636d36b05206d0 Mon Sep 17 00:00:00 2001 From: ilyas Date: Sat, 13 Nov 2021 03:36:16 +0500 Subject: [PATCH 12/23] Fix types error graphql initialize --- src/next/devServer.ts | 6 ++- src/next/graphql/index.ts | 103 ++++++++++++++++++++----------------- src/next/index.ts | 16 +++--- src/next/types/types.v2.ts | 10 +++- 4 files changed, 80 insertions(+), 55 deletions(-) diff --git a/src/next/devServer.ts b/src/next/devServer.ts index a00f4776..47a6e3cf 100644 --- a/src/next/devServer.ts +++ b/src/next/devServer.ts @@ -6,7 +6,11 @@ import { useMailer, useModule, useWebSockets } from "./index"; (async () => { wertik({ port: 1200, - graphql: useGraphql(), + graphql: useGraphql({ + applyMiddlewareOptions: { + path: "/graphl123", + }, + }), database: { jscontainer: useDatabase({ name: "jscontainer", diff --git a/src/next/graphql/index.ts b/src/next/graphql/index.ts index 21f85ee3..eff1524b 100644 --- a/src/next/graphql/index.ts +++ b/src/next/graphql/index.ts @@ -1,50 +1,61 @@ import { get, omit } from "lodash"; import { defaultApolloGraphqlOptions } from "../../framework/defaults/options"; import { ApolloServer } from "apollo-server-express"; -import { GraphqlInitializeProps } from "../types/types.v2"; - -export const useGraphql = (obj?) => obj ?? {}; - -export default function ({ - wertikApp, - expressApp, - store, - configuration, -}: GraphqlInitializeProps) { - store.graphql.typeDefs = store.graphql.typeDefs.concat( - get(configuration, "graphql.typeDefs", "") - ); - - store.graphql.resolvers.Query = { - ...store.graphql.resolvers.Query, - ...get(configuration, "graphql.resolvers.Query", {}), +import { + GraphqlInitializeProps, + iObject, + useGraphqlProps, +} from "../types/types.v2"; + +export const useGraphql = (props: useGraphqlProps) => { + return ({ + wertikApp, + expressApp, + store, + configuration, + }: GraphqlInitializeProps) => { + store.graphql.typeDefs = store.graphql.typeDefs.concat( + get(configuration, "graphql.typeDefs", "") + ); + + store.graphql.resolvers.Query = { + ...store.graphql.resolvers.Query, + ...get(configuration, "graphql.resolvers.Query", {}), + }; + + store.graphql.resolvers.Mutation = { + ...store.graphql.resolvers.Mutation, + ...get(configuration, "graphql.resolvers.Mutation", {}), + }; + + const options = { ...get(configuration, "graphql.options", {}) }; + + const GraphqlApolloServer = new ApolloServer({ + typeDefs: store.graphql.typeDefs, + resolvers: { + ...store.graphql.resolvers, + }, + ...defaultApolloGraphqlOptions, + ...omit(options, ["context"]), + context: async () => { + let contextFromOptions = await get( + options, + "context", + function () {} + )(); + + return { + wertik: wertikApp, + ...contextFromOptions, + }; + }, + }); + + GraphqlApolloServer.applyMiddleware({ + app: expressApp, + ...(props?.applyMiddlewareOptions ?? {}), + }); + + return GraphqlApolloServer; }; - - store.graphql.resolvers.Mutation = { - ...store.graphql.resolvers.Mutation, - ...get(configuration, "graphql.resolvers.Mutation", {}), - }; - - const options = { ...get(configuration, "graphql.options", {}) }; - - const GraphqlApolloServer = new ApolloServer({ - typeDefs: store.graphql.typeDefs, - resolvers: { - ...store.graphql.resolvers, - }, - ...defaultApolloGraphqlOptions, - ...omit(options, ["context"]), - context: async () => { - let contextFromOptions = await get(options, "context", function () {})(); - - return { - wertik: wertikApp, - ...contextFromOptions, - }; - }, - }); - - GraphqlApolloServer.applyMiddleware({ app: expressApp }); - - return GraphqlApolloServer; -} +}; diff --git a/src/next/index.ts b/src/next/index.ts index c28023a2..a191d308 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -1,6 +1,5 @@ import { get } from "lodash"; import express from "express"; -import graphql from "./graphql/index"; import store from "./store"; import { applyRelationshipsFromStoreToDatabase, @@ -30,6 +29,7 @@ export default async function (configuration: WertikConfiguration) { modules: {}, database: {}, mailer: {}, + graphql: {}, }; const port = get(configuration, "port", 5050); @@ -85,11 +85,15 @@ export default async function (configuration: WertikConfiguration) { wertikApp.sendEmail = emailSender(wertikApp); if (configuration.graphql) { - wertikApp.graphql = graphql({ - wertikApp, - expressApp: app, - store, - configuration, + Object.keys(configuration.graphql).forEach((graphqlName, index) => { + wertikApp.graphql[graphqlName] = configuration.graphql[graphqlName]({ + app: wertikApp, + store: store, + configuration: configuration, + expressApp: app, + graphqlName: graphqlName, + isDefaultServer: index === 0, + }); }); } diff --git a/src/next/types/types.v2.ts b/src/next/types/types.v2.ts index dc4556c0..2a7abb12 100644 --- a/src/next/types/types.v2.ts +++ b/src/next/types/types.v2.ts @@ -1,7 +1,11 @@ -import { ApolloServer } from "apollo-server-express"; +import { ApolloServer, GetMiddlewareOptions } from "apollo-server-express"; import { Sequelize } from "sequelize/types"; import { useDatabaseProps, WertikDatabase } from "./types"; +export interface GetMiddlewareOptionsGraphql extends GetMiddlewareOptions { + path: string; +} + export type iObject = { [key: string]: any }; export interface ModuleProps { @@ -88,8 +92,9 @@ export interface WertikConfiguration { }; graphql?: ({ store: Store, - wertikApp: WertikApp, configuration: WertikConfiguration, + wertikApp: WertikApp, + expressApp: any, }) => iObject; cronJobs?: (prop: useCronJobsProps) => () => iObject; } @@ -116,6 +121,7 @@ export interface useGraphqlProps { options?: { [key: string]: any; }; + applyMiddlewareOptions?: GetMiddlewareOptionsGraphql; resolvers?: { Mutation: {}; Query: {}; From 30d302a0095e4a4e3f17e7f1394a236d5b1cf5c3 Mon Sep 17 00:00:00 2001 From: ilyas Date: Sat, 13 Nov 2021 05:23:08 +0500 Subject: [PATCH 13/23] Remove old graphql code --- src/next/devServer.ts | 2 +- src/next/index.ts | 14 +++++--------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/next/devServer.ts b/src/next/devServer.ts index 47a6e3cf..bc2b22d7 100644 --- a/src/next/devServer.ts +++ b/src/next/devServer.ts @@ -8,7 +8,7 @@ import { useMailer, useModule, useWebSockets } from "./index"; port: 1200, graphql: useGraphql({ applyMiddlewareOptions: { - path: "/graphl123", + path: "/graphql", }, }), database: { diff --git a/src/next/index.ts b/src/next/index.ts index a191d308..eea87529 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -85,15 +85,11 @@ export default async function (configuration: WertikConfiguration) { wertikApp.sendEmail = emailSender(wertikApp); if (configuration.graphql) { - Object.keys(configuration.graphql).forEach((graphqlName, index) => { - wertikApp.graphql[graphqlName] = configuration.graphql[graphqlName]({ - app: wertikApp, - store: store, - configuration: configuration, - expressApp: app, - graphqlName: graphqlName, - isDefaultServer: index === 0, - }); + wertikApp.graphql = configuration.graphql({ + wertikApp: wertikApp, + store: store, + configuration: configuration, + expressApp: app, }); } From 2ebe491f57f37f8abcc2ba94c1abf81ef492c0a7 Mon Sep 17 00:00:00 2001 From: ilyas Date: Sat, 13 Nov 2021 07:50:53 +0500 Subject: [PATCH 14/23] v3 types and fixed initializing of features --- src/next/cronJobs/index.ts | 40 ++++++++++++------------- src/next/devServer.ts | 21 +++++++++++++ src/next/index.ts | 36 +++++++++++++++++++---- src/next/sockets/index.ts | 60 ++++++++++++++++++++++---------------- src/next/storage/index.ts | 27 +++++++++++------ src/next/types/types.ts | 5 ++-- src/next/types/types.v2.ts | 19 +++++++----- 7 files changed, 140 insertions(+), 68 deletions(-) diff --git a/src/next/cronJobs/index.ts b/src/next/cronJobs/index.ts index 3b9739f3..3feee7e3 100644 --- a/src/next/cronJobs/index.ts +++ b/src/next/cronJobs/index.ts @@ -1,24 +1,24 @@ import { get } from "lodash"; import nodeCron from "node-cron"; +import { WertikApp } from "../types/types"; +import { + iObject, + useCronJobsProps, + WertikConfiguration, +} from "../types/types.v2"; -export const useCronJob = (obj) => { - return obj; +export const useCronJob = (cron: useCronJobsProps) => { + return ({ + configuration, + wertikApp, + }: { + configuration: WertikConfiguration; + wertikApp: WertikApp; + }) => { + return nodeCron.schedule(cron.expression, () => { + get(cron, "beforeRun", () => {})(wertikApp); + cron.handler(wertikApp); + get(cron, "afterRun", () => {})(wertikApp); + }) as iObject; + }; }; - -const fn = function () {}; - -export default function (app, wertikApp) { - Object.keys(app.cronJobs).forEach((element) => { - const cron = app.cronJobs[element]; - if (cron) { - app.cronJobs[element] = wertikApp.cronJobs[element] = nodeCron.schedule( - cron.expression, - () => { - get(cron, "beforeRun", fn)(app); - cron.handler(app); - get(cron, "afterRun", fn)(app); - } - ); - } - }); -} diff --git a/src/next/devServer.ts b/src/next/devServer.ts index bc2b22d7..c70f1948 100644 --- a/src/next/devServer.ts +++ b/src/next/devServer.ts @@ -1,7 +1,9 @@ +import { useCronJob } from "./cronJobs"; import { useDatabase } from "./database"; import { useGraphql } from "./graphql"; import wertik from "./index"; import { useMailer, useModule, useWebSockets } from "./index"; +import { useStorage } from "./storage"; (async () => { wertik({ @@ -20,6 +22,25 @@ import { useMailer, useModule, useWebSockets } from "./index"; username: "root", }), }, + sockets: { + mySockets: useWebSockets({ + path: "/sockets.wo", + }), + }, + storage: { + dropbox: useStorage({ + for: "dropbox", + dropboxOptions: { + accessToken: "asda", + }, + }), + }, + cronJobs: { + aCronJobName: useCronJob({ + handler: () => console.log(1), + expression: "*/10 * * * * *", + }), + }, mailer: { mail: useMailer(), }, diff --git a/src/next/index.ts b/src/next/index.ts index eea87529..bd669800 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -6,9 +6,7 @@ import { applyRelationshipsFromStoreToGraphql, } from "./database"; import { emailSender } from "./mailer/index"; -import cronJobs from "./cronJobs"; import storage from "./storage/index"; -import sockets from "./sockets"; import http from "http"; import { WertikConfiguration } from "./types/types.v2"; import { WertikApp } from "./types/types.v2"; @@ -30,6 +28,9 @@ export default async function (configuration: WertikConfiguration) { database: {}, mailer: {}, graphql: {}, + sockets: {}, + cronJobs: {}, + storage: {}, }; const port = get(configuration, "port", 5050); @@ -44,9 +45,32 @@ export default async function (configuration: WertikConfiguration) { wertikApp.mailer[mailName] = configuration.mailer[mailName]; } - configuration.cronJobs && cronJobs(configuration, wertikApp); - configuration.storage && storage(configuration, wertikApp); - configuration.sockets && sockets(configuration, wertikApp); + if (configuration.storage) { + for (const storageName of Object.keys(configuration.storage)) { + wertikApp.storage[storageName] = configuration.storage[storageName]({ + configuration: configuration, + wertikApp: wertikApp, + }); + } + } + + if (configuration.cronJobs) { + for (const cronName of Object.keys(configuration.cronJobs)) { + wertikApp.cronJobs[cronName] = configuration.cronJobs[cronName]({ + configuration: configuration, + wertikApp: wertikApp, + }); + } + } + + if (configuration.sockets) { + for (const socketName of Object.keys(configuration.sockets)) { + wertikApp.sockets[socketName] = configuration.sockets[socketName]({ + configuration: configuration, + wertikApp: wertikApp, + }); + } + } if (configuration.database) { for (const databaseName of Object.keys(configuration.database)) { @@ -98,6 +122,8 @@ export default async function (configuration: WertikConfiguration) { next(); }); + console.log(wertikApp.storage); + setTimeout(async () => { if (skip === false) { httpServer.listen(port, () => { diff --git a/src/next/sockets/index.ts b/src/next/sockets/index.ts index dc2d5e03..d4b761c4 100644 --- a/src/next/sockets/index.ts +++ b/src/next/sockets/index.ts @@ -1,54 +1,64 @@ -import { isFunction } from "lodash"; import { Server as SocketIOServer } from "socket.io"; import { Server as WebSocketServer, ServerOptions as WebSocketServerOptions, } from "ws"; +import { WertikApp } from "../types/types"; +import { WertikConfiguration } from "../types/types.v2"; -export const useWebSockets = (configuration: WebSocketServerOptions = {}) => { - return (props, app) => { - if (!configuration.path) { +export const useWebSockets = (props: WebSocketServerOptions = {}) => { + return ({ + configuration, + wertikApp, + }: { + configuration: WertikConfiguration; + wertikApp: WertikApp; + }) => { + if (!props.path) { throw new Error("Path must be passed for useWebSockets"); } console.log( - `Web Sockets server starting at ws://localhost:${props.port}${configuration.path}` + `Web Sockets server starting at ws://localhost:${configuration.port}${props.path}` ); return new WebSocketServer({ - server: app.httpServer, - ...configuration, + server: wertikApp.httpServer, + ...props, }); }; }; export const useIndependentWebSocketsServer = ( - configuration: WebSocketServerOptions = {} + props: WebSocketServerOptions = {} ) => { - return (props, app) => { + return ({ + configuration, + wertikApp, + }: { + configuration: WertikConfiguration; + wertikApp: WertikApp; + }) => { console.log( - `Web Sockets server starting at ws://localhost:${configuration.port}${configuration.path}` + `Web Sockets server starting at ws://localhost:${configuration.port}${props.path}` ); return new WebSocketServer({ - ...configuration, + ...props, }); }; }; -export const useSocketIO = (configuration: any = {}) => { - return (props, app) => { +export const useSocketIO = (props: any = {}) => { + return ({ + configuration, + wertikApp, + }: { + configuration: WertikConfiguration; + wertikApp: WertikApp; + }) => { console.log( - `Socket.IO server starting at http://localhost:${props.port}${ - configuration.path ?? "/socket.io" + `Socket.IO server starting at http://localhost:${configuration.port}${ + props.path ?? "/socket.io" }` ); - return new SocketIOServer(app.httpServer, configuration); + return new SocketIOServer(wertikApp.httpServer, props); }; }; - -export default function (props, app) { - Object.keys(props.sockets).forEach((element) => { - const socket = props.sockets[element]; - if (isFunction(socket)) { - socket(props, app); - } - }); -} diff --git a/src/next/storage/index.ts b/src/next/storage/index.ts index bd27b093..d95dea58 100644 --- a/src/next/storage/index.ts +++ b/src/next/storage/index.ts @@ -1,12 +1,17 @@ +import { WertikApp } from "../types/types"; +import { useStorageProps, WertikConfiguration } from "../types/types.v2"; + const DIGITAL_OCEAN = "digitalocean"; const DROPBOX = "dropbox"; -export const useStorage = (obj) => obj; - -export default function (props, wertikApp) { - Object.keys(props.storage).forEach((element) => { - const storageItem = props.storage[element]; - +export const useStorage = (storageItem: useStorageProps) => { + return ({ + configuration, + wertikApp, + }: { + configuration: WertikConfiguration; + wertikApp: WertikApp; + }) => { if (storageItem.for === DIGITAL_OCEAN) { const digitalOceanSpacesDetails = storageItem.digitalOceanOptions; @@ -25,7 +30,7 @@ export default function (props, wertikApp) { endpoint: spacesEndpoint, }); - props.storage[element] = wertikApp.storage[element] = { + return { spacesEndpoint, s3, }; @@ -36,9 +41,13 @@ export default function (props, wertikApp) { accessToken: dropdboxDetails.accessToken, }); - props.storage[element] = wertikApp.storage[element] = { + return { dropbox: dropboxInstance, }; } - }); + }; +}; + +export default function (props, wertikApp) { + Object.keys(props.storage).forEach((element) => {}); } diff --git a/src/next/types/types.ts b/src/next/types/types.ts index 36ecef78..563508d1 100644 --- a/src/next/types/types.ts +++ b/src/next/types/types.ts @@ -1,5 +1,6 @@ +import { httpstatus } from "aws-sdk/clients/glacier"; import { Express } from "express"; -import { Http2Server } from "http2"; +import { Server } from "http"; import { Sequelize } from "sequelize/types"; export interface NextConfigurationProps { @@ -25,7 +26,7 @@ export interface NextConfigurationProps { export interface WertikApp { express?: Express; - server?: Http2Server; + httpServer?: Server; port?: number | string; skip: boolean; email: {}; diff --git a/src/next/types/types.v2.ts b/src/next/types/types.v2.ts index 2a7abb12..f10a6f72 100644 --- a/src/next/types/types.v2.ts +++ b/src/next/types/types.v2.ts @@ -72,9 +72,9 @@ export interface WertikConfiguration { }) => iObject; }; storage?: { - [key: string]: (props: useStorageProps) => ({ + [key: string]: ({ configuration: WertikConfiguration, - app: WertikApp, + wertikApp: WertikApp, }) => { spacesEndpoint?: iObject; s3?: iObject; @@ -85,9 +85,9 @@ export interface WertikConfiguration { [key: string]: () => Promise; }; sockets?: { - [key: string]: () => ({ + [key: string]: ({ configuration: WertikConfiguration, - app: WertikApp, + wertikApp: WertikApp, }) => iObject; }; graphql?: ({ @@ -96,13 +96,18 @@ export interface WertikConfiguration { wertikApp: WertikApp, expressApp: any, }) => iObject; - cronJobs?: (prop: useCronJobsProps) => () => iObject; + cronJobs?: { + [key: string]: ({ + configuration: WertikConfiguration, + wertikApp: WertikApp, + }) => iObject; + }; } export interface useCronJobsProps { expression: string; - beforeRun: (app: WertikApp) => void | any; - afterRun: (app: WertikApp) => void | any; + beforeRun?: (app: WertikApp) => void | any; + afterRun?: (app: WertikApp) => void | any; handler: (app: WertikApp) => void | any; } From 37352d6ff0f6dc2078a4b1ce2b416c794d0001ef Mon Sep 17 00:00:00 2001 From: ilyas Date: Sat, 13 Nov 2021 08:07:54 +0500 Subject: [PATCH 15/23] Remove unused variables --- src/next/index.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/next/index.ts b/src/next/index.ts index bd669800..852274d0 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -6,7 +6,6 @@ import { applyRelationshipsFromStoreToGraphql, } from "./database"; import { emailSender } from "./mailer/index"; -import storage from "./storage/index"; import http from "http"; import { WertikConfiguration } from "./types/types.v2"; import { WertikApp } from "./types/types.v2"; @@ -20,7 +19,7 @@ export * from "./storage"; export * from "./helpers/modules/backup"; export * from "./sockets"; -export default async function (configuration: WertikConfiguration) { +const Wertik = (configuration: WertikConfiguration) { return new Promise(async (resolve, reject) => { try { const wertikApp: WertikApp = { @@ -122,8 +121,6 @@ export default async function (configuration: WertikConfiguration) { next(); }); - console.log(wertikApp.storage); - setTimeout(async () => { if (skip === false) { httpServer.listen(port, () => { @@ -138,3 +135,5 @@ export default async function (configuration: WertikConfiguration) { } }); } + +export default Wertik \ No newline at end of file From 8f15ccbaf15dc8c66af8f25dcb4d01ddd16bf9c7 Mon Sep 17 00:00:00 2001 From: ilyas Date: Sat, 13 Nov 2021 08:08:21 +0500 Subject: [PATCH 16/23] Hot fix --- src/next/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/next/index.ts b/src/next/index.ts index 852274d0..0e33d84e 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -19,7 +19,7 @@ export * from "./storage"; export * from "./helpers/modules/backup"; export * from "./sockets"; -const Wertik = (configuration: WertikConfiguration) { +const Wertik = (configuration: WertikConfiguration) => { return new Promise(async (resolve, reject) => { try { const wertikApp: WertikApp = { @@ -134,6 +134,6 @@ const Wertik = (configuration: WertikConfiguration) { reject(e); } }); -} +}; -export default Wertik \ No newline at end of file +export default Wertik; From a557710676d23d262a1b360a6bf9ae64f3e8acfe Mon Sep 17 00:00:00 2001 From: ilyas Date: Thu, 18 Nov 2021 15:12:06 +0500 Subject: [PATCH 17/23] Small types and hot changes --- src/next/database.ts | 13 ++++++++++--- src/next/index.ts | 2 +- src/next/mailer/index.ts | 12 ++++-------- src/next/types/types.ts | 6 ++++-- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/next/database.ts b/src/next/database.ts index 99b12c2a..de037465 100644 --- a/src/next/database.ts +++ b/src/next/database.ts @@ -2,7 +2,8 @@ import { Sequelize } from "sequelize"; import { databaseDefaultOptions } from "../framework/defaults/options"; import { get } from "lodash"; import { paginate } from "./crud/index"; -import { UseDatabaseProps } from "./types/types.v2"; +import { Store, UseDatabaseProps } from "./types/types.v2"; +import { WertikApp } from "./types/types.v2"; export const getAllRelationships = (dbName: String) => { return ` @@ -38,7 +39,10 @@ export const useDatabase = function (obj: UseDatabaseProps) { }; }; -export const applyRelationshipsFromStoreToDatabase = async (store, app) => { +export const applyRelationshipsFromStoreToDatabase = async ( + store: Store, + app: WertikApp +) => { store.database.relationships.forEach((element) => { const currentTable = app.modules[element.currentModule].tableInstance; const referencedTable = app.modules[element.referencedModule].tableInstance; @@ -47,7 +51,10 @@ export const applyRelationshipsFromStoreToDatabase = async (store, app) => { }); }; -export const applyRelationshipsFromStoreToGraphql = async (store, app) => { +export const applyRelationshipsFromStoreToGraphql = async ( + store: Store, + _app: WertikApp +) => { store.database.relationships.forEach((element) => { const oldResolvers = get( store, diff --git a/src/next/index.ts b/src/next/index.ts index 0e33d84e..691ab28b 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -41,7 +41,7 @@ const Wertik = (configuration: WertikConfiguration) => { wertikApp.express = app; for (const mailName of Object.keys(configuration.mailer)) { - wertikApp.mailer[mailName] = configuration.mailer[mailName]; + wertikApp.mailer[mailName] = await configuration.mailer[mailName](); } if (configuration.storage) { diff --git a/src/next/mailer/index.ts b/src/next/mailer/index.ts index 275fc2b2..2b270659 100644 --- a/src/next/mailer/index.ts +++ b/src/next/mailer/index.ts @@ -4,7 +4,7 @@ import { emailSendProps, iObject, WertikApp } from "../types/types.v2"; export const useMailer = (props?: iObject) => { return async () => { - let testAccount = await nodemailer.createTestAccount(); + let testAccount = props ? null : await nodemailer.createTestAccount(); const wertiknodemailerDefaultConfiguration = props ? props @@ -13,16 +13,12 @@ export const useMailer = (props?: iObject) => { port: 587, secure: false, auth: { - user: testAccount.user, - pass: testAccount.pass, + user: testAccount?.user, + pass: testAccount?.pass, }, }; - let transporter = nodemailer.createTransport( - wertiknodemailerDefaultConfiguration - ); - - return transporter; + return nodemailer.createTransport(wertiknodemailerDefaultConfiguration); }; }; diff --git a/src/next/types/types.ts b/src/next/types/types.ts index 563508d1..83eabc8d 100644 --- a/src/next/types/types.ts +++ b/src/next/types/types.ts @@ -1,7 +1,7 @@ import { httpstatus } from "aws-sdk/clients/glacier"; import { Express } from "express"; import { Server } from "http"; -import { Sequelize } from "sequelize/types"; +import { Model, Sequelize } from "sequelize/types"; export interface NextConfigurationProps { port?: number; @@ -43,7 +43,9 @@ export interface WertikDatabase { credentials: WertikDatabaseCredentials; instance: Sequelize; } -export interface WertikModule {} +export interface WertikModule { + tableInstance: Model; +} export interface WertikDatabaseCredentials { port: number; password: string; From 50a52a06146dfcd6a1e67627999fa7f1667f6e5b Mon Sep 17 00:00:00 2001 From: ilyas Date: Thu, 18 Nov 2021 15:17:29 +0500 Subject: [PATCH 18/23] Change app to express app --- src/next/index.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/next/index.ts b/src/next/index.ts index 691ab28b..4366e8ef 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -34,11 +34,11 @@ const Wertik = (configuration: WertikConfiguration) => { const port = get(configuration, "port", 5050); const skip = get(configuration, "skip", false); - const app = get(configuration, "express", express()); - const httpServer = http.createServer(app); + const expressApp = get(configuration, "express", express()); + const httpServer = http.createServer(expressApp); wertikApp.httpServer = httpServer; - wertikApp.express = app; + wertikApp.express = expressApp; for (const mailName of Object.keys(configuration.mailer)) { wertikApp.mailer[mailName] = await configuration.mailer[mailName](); @@ -98,7 +98,7 @@ const Wertik = (configuration: WertikConfiguration) => { } } - app.get("/w/info", function (req, res) { + expressApp.get("/w/info", function (req, res) { res.json({ message: "You are running wertik-js", version: require("./../../package.json").version, @@ -112,11 +112,11 @@ const Wertik = (configuration: WertikConfiguration) => { wertikApp: wertikApp, store: store, configuration: configuration, - expressApp: app, + expressApp: expressApp, }); } - app.use(async function (req, res, next) { + expressApp.use(async function (req, res, next) { req.wertik = wertikApp; next(); }); From 9763a56dc11fe14f7a23c498be66ecfdc82272cb Mon Sep 17 00:00:00 2001 From: ilyas Date: Thu, 18 Nov 2021 15:45:01 +0500 Subject: [PATCH 19/23] Small Fixes --- package.json | 2 +- src/framework/graphql/index.ts | 2 -- src/next/index.ts | 6 ++++-- src/next/types/types.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index fd8a5bea..128f958f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wertik-js", - "version": "3.0.8-beta", + "version": "3.1.0-beta", "main": "lib/main.js", "types": "lib/types.d.ts", "repository": "https://github.com/Uconnect-Technologies/wertik-js.git", diff --git a/src/framework/graphql/index.ts b/src/framework/graphql/index.ts index 1da12abd..0a5fec2a 100644 --- a/src/framework/graphql/index.ts +++ b/src/framework/graphql/index.ts @@ -7,8 +7,6 @@ import GraphQLJSON, { GraphQLJSONObject } from "graphql-type-json"; import { ApolloServer } from "apollo-server-express"; import * as auth from "./../helpers/auth"; -//expressApp,configuration,models,emailTemplates,sendEmail,database,WertikEventEmitter - export default async function (options: IGraphQLInitialize) { const { mailerInstance, diff --git a/src/next/index.ts b/src/next/index.ts index 4366e8ef..b6d5e69b 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -19,7 +19,9 @@ export * from "./storage"; export * from "./helpers/modules/backup"; export * from "./sockets"; -const Wertik = (configuration: WertikConfiguration) => { +const Wertik: (configuration: WertikConfiguration) => Promise = ( + configuration: WertikConfiguration +) => { return new Promise(async (resolve, reject) => { try { const wertikApp: WertikApp = { @@ -116,7 +118,7 @@ const Wertik = (configuration: WertikConfiguration) => { }); } - expressApp.use(async function (req, res, next) { + expressApp.use(async function (req, _res, next) { req.wertik = wertikApp; next(); }); diff --git a/src/next/types/types.ts b/src/next/types/types.ts index 83eabc8d..d98b8734 100644 --- a/src/next/types/types.ts +++ b/src/next/types/types.ts @@ -91,7 +91,7 @@ export interface useModuleProps { on?: (obj: { useQuery: (props: useQueryProps) => {} | void; useMutation: (props: useMutationProps) => {} | void; - useExpress: (props: useExpressProps) => {} | void; + useExpress: (express: any) => void; hasOne: (props: RelationParams) => {} | void; belongsTo: (props: RelationParams) => {} | void; belongsToMany: (props: RelationParams) => {} | void; From cc742926f5ddfa0ee91ea3f549e0e5115ba647c8 Mon Sep 17 00:00:00 2001 From: ilyas Date: Thu, 18 Nov 2021 21:48:52 +0500 Subject: [PATCH 20/23] Added createOrUpdate and types coverage --- src/next/crud/index.ts | 39 +++++++++++++++++++++++++++++++++++++ src/next/modules/modules.ts | 2 +- src/next/types/types.ts | 12 +++++++++++- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/next/crud/index.ts b/src/next/crud/index.ts index e7a3998b..b227a5d3 100644 --- a/src/next/crud/index.ts +++ b/src/next/crud/index.ts @@ -1,3 +1,4 @@ +import { ApolloError } from "apollo-server-express"; import { get } from "lodash"; import convertFiltersIntoSequalizeObject from "./../../framework/database/helpers/convertFiltersIntoSequalizeObject"; @@ -62,12 +63,50 @@ export default function (module, schemaInformation, store) { update${module.name}(input: update${module.name}Input,where: ${module.name}FilterInput!): ${module.name}BulkMutationResponse create${module.name}(input: [create${module.name}Input]): ${module.name}BulkMutationResponse delete${module.name}(where: ${module.name}FilterInput!): SuccessResponse + createOrUpdate${module.name}(id: Int, input: create${module.name}Input): ${module.name} } `; }, generateCrudResolvers() { return { Mutation: { + [`createOrUpdate${module.name}`]: get( + module, + "graphql.mutations.createOrUpdate", + async (_, args, context, info) => { + const argsFromEvent = await get( + module, + "events.beforeCreateOrUpdate", + function () {} + )(_, args, context, info); + args = argsFromEvent ? argsFromEvent : args; + const id = args.id; + let ___find: any; + if (id) { + ___find = await schemaInformation.tableInstance.findOne({ + where: { + id: id, + }, + }); + + if (!___find) { + throw new Error(`${module.name} Not found`); + } + + await schemaInformation.tableInstance.update(args.input, { + where: { id: id }, + }); + + return await schemaInformation.tableInstance.findOne({ + where: { id: id }, + }); + } else { + return await schemaInformation.tableInstance.create( + args.input + ); + } + } + ), [`update${module.name}`]: get( module, "graphql.mutations.update", diff --git a/src/next/modules/modules.ts b/src/next/modules/modules.ts index cf49cd93..8b33109f 100644 --- a/src/next/modules/modules.ts +++ b/src/next/modules/modules.ts @@ -1,4 +1,4 @@ -import { get, isFunction } from "lodash"; +import { get } from "lodash"; import crud from "../crud"; import { databaseDefaultOptions } from "../../framework/defaults/options"; import { RelationParams, useModuleProps } from "../types/types"; diff --git a/src/next/types/types.ts b/src/next/types/types.ts index d98b8734..815cfc7e 100644 --- a/src/next/types/types.ts +++ b/src/next/types/types.ts @@ -2,6 +2,7 @@ import { httpstatus } from "aws-sdk/clients/glacier"; import { Express } from "express"; import { Server } from "http"; import { Model, Sequelize } from "sequelize/types"; +import { iObject } from "./types.v2"; export interface NextConfigurationProps { port?: number; @@ -84,9 +85,17 @@ export interface useModuleProps { useDatabase: boolean; table?: string; database?: string; - tableOptions?: any; + tableOptions?: iObject; graphql?: { schema?: string; + updateSchema?: string; + createSchema: string; + mutations?: { + update?: Function; + delete?: Function; + create?: Function; + createOrUpdate?: Function; + }; }; on?: (obj: { useQuery: (props: useQueryProps) => {} | void; @@ -105,6 +114,7 @@ export interface useModuleProps { beforeCreate?: Function; beforeDelete?: Function; beforeUpdate?: Function; + beforeCreateOrUpdate?: Function; }; } export interface useQueryProps { From 52a6fe999832b2d089008b84988fc34a90145404 Mon Sep 17 00:00:00 2001 From: ilyas Date: Thu, 18 Nov 2021 21:55:51 +0500 Subject: [PATCH 21/23] Remove unsued variable --- src/next/crud/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/next/crud/index.ts b/src/next/crud/index.ts index b227a5d3..cd257b1c 100644 --- a/src/next/crud/index.ts +++ b/src/next/crud/index.ts @@ -1,4 +1,3 @@ -import { ApolloError } from "apollo-server-express"; import { get } from "lodash"; import convertFiltersIntoSequalizeObject from "./../../framework/database/helpers/convertFiltersIntoSequalizeObject"; From 551635c567fc201e9d64995b4abeb92997030f83 Mon Sep 17 00:00:00 2001 From: ilyas Date: Sun, 21 Nov 2021 13:08:58 +0500 Subject: [PATCH 22/23] Hot fixes in next version. datetime support in graphql, added to cron jobs. --- src/next/devServer.ts | 4 +++- src/next/index.ts | 12 ++++++------ src/next/modules/modules.ts | 1 + src/next/types/types.v2.ts | 1 + 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/next/devServer.ts b/src/next/devServer.ts index c70f1948..1b694aaf 100644 --- a/src/next/devServer.ts +++ b/src/next/devServer.ts @@ -2,7 +2,8 @@ import { useCronJob } from "./cronJobs"; import { useDatabase } from "./database"; import { useGraphql } from "./graphql"; import wertik from "./index"; -import { useMailer, useModule, useWebSockets } from "./index"; +import { useModule, useWebSockets } from "./index"; +import { useMailer } from "./mailer"; import { useStorage } from "./storage"; (async () => { @@ -37,6 +38,7 @@ import { useStorage } from "./storage"; }, cronJobs: { aCronJobName: useCronJob({ + name: "Send emails to people every 1 minute", handler: () => console.log(1), expression: "*/10 * * * * *", }), diff --git a/src/next/index.ts b/src/next/index.ts index b6d5e69b..e247af83 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -42,12 +42,12 @@ const Wertik: (configuration: WertikConfiguration) => Promise = ( wertikApp.httpServer = httpServer; wertikApp.express = expressApp; - for (const mailName of Object.keys(configuration.mailer)) { + for (const mailName of Object.keys(configuration.mailer || {})) { wertikApp.mailer[mailName] = await configuration.mailer[mailName](); } if (configuration.storage) { - for (const storageName of Object.keys(configuration.storage)) { + for (const storageName of Object.keys(configuration.storage || {})) { wertikApp.storage[storageName] = configuration.storage[storageName]({ configuration: configuration, wertikApp: wertikApp, @@ -56,7 +56,7 @@ const Wertik: (configuration: WertikConfiguration) => Promise = ( } if (configuration.cronJobs) { - for (const cronName of Object.keys(configuration.cronJobs)) { + for (const cronName of Object.keys(configuration.cronJobs || {})) { wertikApp.cronJobs[cronName] = configuration.cronJobs[cronName]({ configuration: configuration, wertikApp: wertikApp, @@ -65,7 +65,7 @@ const Wertik: (configuration: WertikConfiguration) => Promise = ( } if (configuration.sockets) { - for (const socketName of Object.keys(configuration.sockets)) { + for (const socketName of Object.keys(configuration.sockets || {})) { wertikApp.sockets[socketName] = configuration.sockets[socketName]({ configuration: configuration, wertikApp: wertikApp, @@ -74,7 +74,7 @@ const Wertik: (configuration: WertikConfiguration) => Promise = ( } if (configuration.database) { - for (const databaseName of Object.keys(configuration.database)) { + for (const databaseName of Object.keys(configuration.database || {})) { try { wertikApp.database[databaseName] = await configuration.database[ databaseName @@ -89,7 +89,7 @@ const Wertik: (configuration: WertikConfiguration) => Promise = ( applyRelationshipsFromStoreToGraphql(store, wertikApp); if (configuration.modules) { - for (const moduleName of Object.keys(configuration.modules)) { + for (const moduleName of Object.keys(configuration.modules || {})) { wertikApp.modules[moduleName] = await configuration.modules[ moduleName ]({ diff --git a/src/next/modules/modules.ts b/src/next/modules/modules.ts index 8b33109f..166352fb 100644 --- a/src/next/modules/modules.ts +++ b/src/next/modules/modules.ts @@ -195,6 +195,7 @@ export const useModule = (props: useModuleProps) => { tableInformation.forEach((element, _index) => { if ( element.Type.includes("timestamp") || + element.Type.includes("datetime") || element.Type.includes("varchar") || element.Type.includes("text") ) { diff --git a/src/next/types/types.v2.ts b/src/next/types/types.v2.ts index f10a6f72..b9e7755a 100644 --- a/src/next/types/types.v2.ts +++ b/src/next/types/types.v2.ts @@ -106,6 +106,7 @@ export interface WertikConfiguration { export interface useCronJobsProps { expression: string; + name: string; beforeRun?: (app: WertikApp) => void | any; afterRun?: (app: WertikApp) => void | any; handler: (app: WertikApp) => void | any; From acd3fa4ee392ee08936256a840508cf5b0c9ea71 Mon Sep 17 00:00:00 2001 From: ilyas Date: Tue, 23 Nov 2021 20:41:54 +0500 Subject: [PATCH 23/23] Response change --- src/next/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/next/index.ts b/src/next/index.ts index e247af83..16a2fabc 100644 --- a/src/next/index.ts +++ b/src/next/index.ts @@ -102,7 +102,7 @@ const Wertik: (configuration: WertikConfiguration) => Promise = ( expressApp.get("/w/info", function (req, res) { res.json({ - message: "You are running wertik-js", + message: "You are running wertik-js v3", version: require("./../../package.json").version, }); });