Coder Social home page Coder Social logo

mandarineorg / mandarinets Goto Github PK

View Code? Open in Web Editor NEW
274.0 14.0 13.0 22.34 MB

Mandarine.TS is a typescript, decorator-driven framework that allows you to create server-side applications. Mandarine.TS provides a range of built-in solutions such as Dependency Injection, Components, ORM and more. Under its umbrella, Mandarine.TS has 4 modules: Core, Data, Security and MVC, these modules will offer you the requirements to build a Mandarine-powered application.

Home Page: https://www.mandarinets.org/

License: MIT License

TypeScript 99.99% Shell 0.01%
typescript dependency-injection mvc mandarine deno denoland framework typescript-framework enterprise orm

mandarinets's Introduction

Mandarine.TS

MandarineTS CI deno doc

MandarineTS. A minimalist, decorator-driven, MVC, typescript framework for Deno.

Description

Mandarine is a typescript framework that runs on Deno. Mandarine is used to create scalable and reliable server-side solutions. With the use of OOP (Object-oriented programming) and the benefits of Typescript, Mandarine makes sure to give you a better coding experience not only in terms of design patterns such as Dependency Injection but in terms of readability for enterprise code.

Mandarine is divided into 4 different cores that are used to accomplish the same objective: A high-quality enterprise solution. These cores are: Core, MVC, Data & Security. The 4 different cores perform different tasks in order to bring modularity to your application.

For its MVC Core, Mandarine uses Oak under the hood as its main HTTP dispatcher.

Documentation

To see all the available documentation of Mandarine.TS, please Click here.
Don't know where to start? Click here for our quickstart

Basic usage

import { MandarineCore, Controller, GET } from "https://deno.land/x/[email protected]/mod.ts"; 

@Controller('/api')
export class Boo {
     
    @GET('/hello-world')
    public helloWorld(): string {
        return "Hello World";
    }

}

new MandarineCore().MVC().run();

# request => http://localhost:4444/api/hello-world => Hello World

Questions

For questions & community support, please visit our Discord Channel or join us on our twitter.

MandarineTS Main features

Built-in Dependency Injection Framework, Components, Routes, Middleware, Sessions, built-in ORM, MQL (Mandarine Query Language), Template Engine, built-in authentication

Want to help?

Interested in coding

In order to submit improvements to the code, open a PR and wait for it to review. We appreciate you doing this.

Not interested in coding

We would love to have you in our community, please submit an issue to provide information about a bug, feature, or improvement you would like.

Follow us wherever we are going

mandarinets's People

Contributors

andreespirela avatar buttercubz avatar codingknite avatar fusselwurm avatar martincrb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mandarinets's Issues

app.json

[Details]
Mandarine should have a optional app.json file in the current working directory. This file would indicate where our properties are, as well as other config that Mandarine may need at Deno compile time.

Throw error if "denoEnv" from mandarine.json has properties that are not string

[Details]
Right now, if you have a mandarine.json file, and you put properties inside denoEnv, they will be sent to the environmental variables. But we are not checking whether the person puts only string as values, meaning, we are not checking the developer is respecting
[prop: string]: string.

[Expected behavior]
Error should be thrown during MCT if the developer does not respect the structure of denoEnv

Value decorator for environmental variables should parse "true" or "false" as boolean and not as string

[Details]
Right now, if you use @Value to retrieve environmental variables and one of those variables is either "false" or "true", the response will be given as string. This makes sense since Deno.env does not accept any other type more than String. Although, we want to allow the use of boolean values when retrieving data from environmental variables throguh @Value

[Expected behavior]
When using @Value with environmental variables. If the environmental variable is equal to "false" or "true", we parse it from string to boolean and we return a boolean.

Add integration test for nest.land

Mandarine must have an integration test that confirms Mandarine's latest nest.land module is fully stable. This integration test must run in a different workflow.

Optional should have `map`

[Details]
Optional should handle a method called map which would allow to use Optional in functional programming such as chains and filtering.

Add Support for Middleware targetting methods instead of controllers

[Context]
Right now, in order to use Mandarine's middleware, you need to create a @Middleware component targetting a RegExp of a route. What we want to do now is to add a feature for the developer to add middleware to the method. This can be located under the options of the Http method ex: @GET(route, options) where options would have a middleware field, or we could also create a decorator UseMiddleware.

Collaboration

I read your post on dev.to and saw that you are looking for collaborators so I think that my team and I could help you, we are the developers of Trex package manager.

Preparing Mandarine.ts Framework for production environments

Hello Community,
Today, I am writing this issue to inform a bit about the next steps in order for Mandarine to be production ready.

MandarineTS framework has grown over the past months not only in community but also in functionalities and stability. Our community is still fairly small but that does not mean Mandarine is not moving forward in order to reach its main objective: A all-in-one solution for enterprises.

MandarineTS already has a reliable Dependency Injection System, Components, Middleware, Sessions, Template engine & other modules. We also could say that Mandarine has a reliable ORM system along with MQL (Mandarine Query Language), although this is yet to be improved but it can perfectly be used for large applications.

Case

With that said, I have to admit, I do not consider MandarineTS Framework production ready and I do not recommend it for large applications, it is perfectly fine to use it in small projects or projects with limited traffic but when it comes to the scalability of MandarineTS for production solutions, there are two things that do not make me feel well about MandarineTS in running in large scales:

  • Deno
    • We can't measure the impact of Deno in production environments because Deno is really new. Deno is only in its 1.1.1 version (2020-06-23) and it is yet to be widely used, for instance widely tested.
    • Among other things, Deno still has a lot of questions to be addressed like the multiple modules issue: What if a module goes down, what if the module of a module of a module goes down. Since Deno does not have a package manager like NPM and imports are cached but they are not directly related to our application, it is hard to define or track when a module breaks another module and ends up breaking your application too as well as many other issues you can think of related to this concept.
    • The fact that Deno is very new and its in early versions gives Mandarine a lot of impediments such as working with reliable Database modules, only if the Deno community grows to enterprise levels then Mandarine will be able to support multiple database systems.
  • Mandarine
    • Mandarine has a lot of functionalities and we can say it works in a reliable way, although, the amount of work required to make Mandarine production ready goes along with the amount of collaborators, as of right now (2020-06-23) Mandarine has 0 collaborators but me. This can be a problem as the project grows because the larger it gets the more issues will be submitted and requested.
    • In the same way as Deno, Mandarine is fairly new, it is only in its 1.1.1 version (2020-06-23) which makes measuring the impact it can have on a production environment almost impossible.
      • The fact that Mandarine is in its early versions & it is not as widely used as we would desire makes adding features and solving bugs hard since we, the collaborators, have no reports/issues to work on but our imagination which makes the process of making Mandarine grow slower than expected.
    • Many of the code Mandarine currently uses needs to be better documented and refactored.
      • This includes the creation of Unit tests.

Steps to be Production Ready

  • The creation of a Testing Framework for Mandarine. It must be able to be not only used for Mandarine internals but also for people using Mandarine.
    • Every core module in Mandarine such as Dependency Injection, Routes... must be unit-tested with this framework.
    • Integration tests should be available for core functionalities
  • MandarineTS repository must have continuous integration
  • Refactoring the code that needs to be refactored such as locating every mandarine-native module (SessionContainer, Default Web configurer, and others) in one folder.
    • Cleaning code
    • Everything in Mandarine should be a factory or a proxy, this way we can perform tests in an easier & cleaner way.
  • Add copyright header to all files
  • Add Benchmarks to documentation in order to be able to measure how good the changes we are making really are.
  • Find collaborators and impulse the use of Mandarine among both communities (JS & Typescript).
  • Evaluate and see how things evolve and develop with the use of Deno across the globe.
  • Document the life cycles of Mandarine Starter and try to make it a flexible life cycle so the user can give it a behavior.
  • Creation of an official website to offer more detailed documentation and things related to Mandarine
  • Define Standards of Mandarine not only for the collaborators but for whoever uses Mandarine out there.
  • Cache folder should be available per every release.

...

In order to achieve a Production Ready status, we need to work on the steps mentioned before, not a few of them, not only two of them, but ALL of them. All the steps mentioned are a top-priority.

Anything you would like to add? Feel free.

Refactor Manual Components

Refactor Manual Components.
We want to refactor manual components and support the concept of "Mandarine Native classes" which can be overridden.

Support Pipes

[Details]
As an user I would like to have the concept of Pipes. Pipes can be useful to transform parameters from a request (query, route params) or even a body request from something like a POST request. The concept behind a pipe is to bind the parameter to the pipe, and the pipe will be processed before the request reaches the HTTP Handler, when the request reaches the HTTP handler, the pipe has transformed x param into a new value.

Denjucks have been temporarily removed

[Details]
The template library for Deno, Denjucks started breaking Mandarine about 4 days ago. While we do not know the exact reasons why this happened, we do know it is an external issue from Mandarine as others reported it too. We suspect this has to do with one of the upgrades from Deno and its compatibility with Denjucks.

[Environment]
This was happening in Windows, we do not have any report of Denjucks affecting MacOS or Ubuntu or Linux. Although, for safety concerns we have disabled it in all environments.

[Tickets]
See #58
See #9 from denjucks

[Mandarine removal]
Denjucks was removed in v1.1.2

[Final decision]
We are exploring removing Denjucks permanently for future versions. This is being evaluated as it could be a breaking change.

[BUG] [Feature] [HOTFIX] Improve Performance

[Details]
Right now, Mandarine is presenting the following performance.

Running 10s test @ http://localhost:1447
  10 threads and 40 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    10.39ms    3.49ms 116.70ms   94.86%
    Req/Sec   392.12     50.56   760.00     89.80%
  39170 requests in 10.06s, 9.97MB read
Requests/sec:   3894.13
Transfer/sec:      0.99MB

As you can see. That is extremely bad.

[Expected behavior]
It should be above 10k per second.

[OS]
MacOS Mojave 10.14.6

[Environment]

  • Mandarine version: 1.2.1
  • deno 1.2.0
  • v8 8.5.216
  • typescript 3.9.2

[Additional]
Thanks the Drashland team for getting the performance for Mandarine.
CC: @crookse , @ebebbington .

Template engine from config is ignored

Hey,
thank you for adding denjucks as a template engine, but now to my issues.
When I configure the engine inside the controller, as it has been done in the examples, it's working, but when I use the config file and set something like this:

    "templateEngine": {
      "path": "./templates",
      "engine": "denjucks"
    }

it won't pick up the configured engine, it's using ejs all the time. So doesn't matter which (valid) engine gets configured, ejs is used all the time.

And (not sure if it is and issue on view_engine), but when using denjucks and then extend tag ( {% extend 'some_template.html' %}), it's not using the configured template path, but the project root. So when using the configured path from above, I have to use {% extend 'templates/some_template.html'%}. I could do some more research if you want and open another issue for that.

Support CRON Jobs

[Context]
As a developer, I want to be able to use Cron jobs. The idea behind this would be a decorator like @CRON which would take a CRON syntax. This decorator would target a handler (a method).

[Bug] @Value decorator is not working

[Information]
@value decorator is not working, it is setting undefined for all properties.

[Reason]
Decorators are initialized at typescript compile time & configuration is initialized at mandarine compile time

Mandarine MVC is allowing multiple same routes.

[Details]
As of right now, Mandarine MVC is not throwing any error when a controller has the same route. Same routes with different HTTP handlers should not be available and an error should be thrown. Also, the verification of same routes needs to be by signature and not by string, this is because.
"/api/:id/:otherParam" & "/api/:otherParam/:id" are completely different strings but they have the same signature, if we validate by string equality then we would be doing nothing.

Same routes with different HTTP Methods

[Current behavior]
Right now, you can't have the same route as an error will be thrown during mandarine-compile time. This is the way it's supposed to be, but it's also happening with different HTTP methods (GET, POST...)

[Expected Behavior]
Same routes must not be allowed under the same HTTP method ,but they may be allowed if they have different HTTP Methods. Mandarine should be smart enough to redirect the request to the right handler.

Mandarine & Mandarine native classes

[Brief]
Mandarine should have the concept of Mandarine native classes.

[Details]
A Mandarine native class would be a class that performs an specific purpose at mandarine compile time or runtime. An example of this would be MandarineMvcConfig, a class where the behavior of the MVC framework would be. By Default, Mandarine should provide a implementation for these type of classes. But through the use of a decorator MandarineOverride, these implementations can get overriden.

[Code Details]
There should a be container where the Mandarine native classes will be located, this container will be a map where the key is the class & the value is the instance. The only way to add to this container is if the overriden implementation instanceof T is false. This would involve that in order to override a class, there should be a generic bridge in order to let mandarine know what class is being overriden, where T is the class we are trying to override.

Mandarine should handle multipart-form/data

[Details]
Mandarine should be able to handle multipart-form/data in @ResponseBody or the body of a request.

[Impediment]
Waiting for Oak to fix current bug regarding multipart-form/data

[Feature] Provide greaterThan & lessThan for MQL

[Details]
We want to provide the operators/keywords greaterThan & lessThan for MQL

[Investigation]
Inside the orm-core module, there is a folder called repository*. This folder contains a file called repositoryPostgresProxy.ts, the class inside that file contains the method lexicalProcessor. The method lexicalProcessor handles the parsing of the SQL operators. See more here.
Add to the lexical processor, support for greaterThan & lessThan.

Since greaterThan & lessThan will need a value, the variable colSecureId (

let colSecureId = 1;

) will need to be incremented.

Any question on this good first issue? Ask me.

[Production Steps] Refactor & clean code.

[Details]
There are a lot of lines of code that are either repeated or can be improved. The core is also kind of messy as some sections of the core are distributed in many files which is not really proper. .env files should be supported. The mandarine compiler text should be shown first, Core should load inside an anonymous function...

Note This is a "Production Step" ticket. This means, this is a ticket that will highly affect Mandarine as it is part of the plan for Mandarine to be production ready. See more here

Deploy method

Mandarine should have a deploy method part of MandarineCore. When this method is called it will retrieve all the dependencies (from deno cache) the application is using and put in the project's folder inside a new folder called target/sources

Create a "FAQ" tab on the documentation and add lifecycles

Create a "FAQ" tab on the documentation and add lifecycles.
We want to have as many precise information about Mandarine's lifecycles as possible. This includes lifecycles for the general mandarine core, lifecycle for requests, etc.

Unsupported compiler options: allowUmdGlobalAccess

[Details]
When running an app with allowUmdGlobalaccess inside the tsconfig.json (as notes in the docs), i get a warning that it is't supported, and ignores it anyway:

// tsconfig.json
{
  "compilerOptions": {
    "strict": false,
    "noImplicitAny": false,
    "noImplicitThis": false,
    "alwaysStrict": false,
    "strictNullChecks": false,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": false,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "allowUmdGlobalAccess": false
  }
}

This doesn't break anything

[Stacktrace]
Edwards-MacBook-Pro:benchmarks edwardbebbington$ deno run -A --config tsconfig.json mandarinets.ts
Check file:///mandarinets.ts
Unsupported compiler options in "/tsconfig.json"
The following options were ignored:
allowUmdGlobalAccess

[Scenario]
Steps to reproduce the behavior:

  1. Create a basic mandarinets file:
// app.ts
import { Controller, GET, MandarineCore } from "https://deno.land/x/mandarinets/mod.ts";

@Controller()
export class MyController {

  @GET('/')
  public helloWorld() {
    return `Hello World!`;
  }

}

new MandarineCore().MVC().run();

console.log("Server started")
  1. Create the tsconfig:
{
  "compilerOptions": {
    "strict": false,
    "noImplicitAny": false,
    "noImplicitThis": false,
    "alwaysStrict": false,
    "strictNullChecks": false,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": false,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "allowUmdGlobalAccess": false
  }
}
  1. Run the server:
$ deno run -A --config tsconfig.json app.ts

[Expected behavior]
Works as expected, just seems like that config makes no difference?

[OS]
N/A

[Environment]

  • Mandarine version: v1.2.1
  • Deno version :1.2.0
  • Deno v8 version: v8 8.5.216
  • Deno typescript version: 3.9.2

Exception Filters

[Context]
As a developer, I want to be able to create handle HTTP exceptions and return my own messages.

[Production Steps] Create unit tests for every module

[Details]
Mandarine should have unit tests for every module. Things such as Dependency Injection & component creation are modules that we need to be really careful about. We need unit tests for that primarily, but for any other module as well in order to be production ready.

Note This is a "Production Step" ticket. This means, this is a ticket that will highly affect Mandarine as it is part of the plan for Mandarine to be production ready. See more here

Array is not being interpreted as JSON

[Details]
As of right now, when a HTTP Handler returns an array it is being interpreted as HTML giving: Content-Type: text/html in the headers of the response. An array, just like an object, must be interpreted as JSON

[Expected Behavior]
Arrays should be interpreted as JSON for response purposes

[Scenario]

  1. Create a endpoint
  2. return an array
  3. See the response, and see how it is interpreted as text/html

Support for more keywords in MQL

Mandarine Query Language (MQL) should support more keywords in its lexical processor & query builder.

  • greaterThan, greaterThanEqual
  • lessThanEqual, lessThan
  • isNotNull, isNull
  • isEmpty, isNotEmpty
  • like
  • startingWith

Support Guards

[Context]
Guards will be a new kind of middleware. Right now, Mandarine's middleware has two methods onPreRequest and onPostRequest. The idea behind the concept of Guards is it will only have one method which will be validate. It will decide whether the request is valid to be had or no. As of right now, you can achieve this by returning false in onPreRequest of Mandarine's middleware, but we want to take this concept and make it more specific with guards.

[Additional information]
Guards will have their own decorator. This decorator will apply the guard on the target. The possible targets are a controller (class level), or a HTTP handler (route-specific level). Although, an option like middleware where you can provide a RegExp and if it matches the current request URL then it is activated should be available, this way, we can give the developer the ability to use guards for all url that matches x instead of having the person to decorate all the controllers or routes specifically with the wanted match.

Support custom decorators

[Context]
As a developer, I want to be able to create custom decorators, these decorators should have access to the context of the request.

Provide infrastructure for authentication.

[Details]
We want Mandarine to be as straightforward as possible when it comes to back-end development. One of the main issues with back-end development is the amount of time that is spent on creating things like authentication, or registration. With that said, what we want to do is the following:

Mandarine should be able to handle authentication, this means, the developer will already have all the infrastructure to connect their database or array of users to Mandarine, and based on some simple logic and overriding, Mandarine will be able to authenticate. The authentication must happen at Request time, at request time, we will inject the user object to the context of the request if present. This process should be the first in the lifecycle, as when the request gets to the middleware process, the user object should already be injected.

We want to provide the possibility of auto-creating an endpoint for login and registration. All the logic behind that will be handled by Mandarine and the result will be a user object present in the request, or, not user object at all if authentication failed.

We also want the client-side to store the user information, we don't want to store the user's authentication in memory. For this, we will create three cookies (example): Id, Username, Password, signature. The signature will be the union of username and password created by Mandarine during the first request of authentication, if the username or password of the request or the signature itself changes, we can assume the data has been manipulated and the current user in the current request needs re-authentication. Otherwise, if the signature matches the data that was received, then we assume this user is logged-in, and we proceed to inject the data stored on the client's side (the cookies with the login information), this way, we don't have to request the database or the array of users everytime there is a request.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.