0.0.0-0.30 • Published 3 years ago

@prunus/bridge v0.0.0-0.30

Weekly downloads
-
License
MIT
Repository
-
Last release
3 years ago

@prunus/bridge

A library for fast implementation of a rest api integrated with typeorm, express, commander and some front end tools like webpack. It bridges the gap between client and server in a practical way using the standard typeorm repository api so you can use the find, save, remove syntax on the front end and a highly customizable entity manager.


Install server side

yarn add @prunus/bridge express te2ys yup typeorm;
yarn add -D @types/express;
# or
npm install --save @prunus/bridge express te2ys yup typeorm;
npm install --save-dev @types/express;

Install client side

yarn add @prunus/bridge axios
# or
npm install --save @prunus/bridge axios

Using webpack

yarn add @prunus/bridge-webpack-plugin
# or
npm install --save @prunus/bridge-webpack-plugin
import { BridgeWebpackPlugin } '@prunus/bridge-webpack-plugin'

const webpackConfiguration = {
  //  ...webpackConfiguration,
  plugins: [
    // ...webpackConfiguration.plugins,
    new BridgeWebpackPlugin()
  ]
}

Usage

// User.entity.ts
import { Column, CreateDateColumn, DeleteDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm'

export @Entity()
class User {
  @PrimaryGeneratedColumn( 'uuid' ) id: string

  @Column() name: string
  @Column() email: string

  @CreateDateColumn( { type: 'timestamp with time zone' } ) createdAt: Date
  @UpdateDateColumn( { type: 'timestamp with time zone' } ) updatedAt: Date
  @DeleteDateColumn( { type: 'timestamp with time zone' } ) deletedAt: Date
}
// User.bridge.ts
import Bridge from '@prunus/bridge'

const User = Bridge.create( {
  name: 'User',
  uri: 'users',
  getTypeORMEntity: () => import( './User.entity' ).then( module => module.User ),
  getAxiosInstance: () => import( './api.service' ).then( module => module.api )
} )

export default User
// api.service
import Axios from 'axios'

const api = Axios.create()

export { api }
// server.ts
import Express from 'express'
import Bridge from '@prunus/bridge'
import User from './User.bridge'

const app = Express()
app.use( Bridge.handler( User ) )
// web.tsx
import React, { useEffect, useState } from 'react'
import User from './User.bridge'
const App = () => {
  const [ users, setUsers ] = useState( [] )
  const [ loading, setLoading ] = useState( false )
  const [ error, setError ] = useState( null )
  useEffect( () => {
    setLoading( true )
    User.find()
      .then( setUsers )
      .catch( setError )
      .finally( setLoading.bind( null, false ) )
  }, [] )

  if ( loading ) return <h1>Loading...</h1>
  if ( !users.length ) return <h1>Nothing</h1>

  return (
    <ul>
      {users.map( user => (
        <li key={user.id}>{user.name}</li>
      ) )}
    </ul>
  )
}
// webpack.config.ts
import { BridgeWebpackPlugin } from '@prunus/bridge-webpack-plugin'

const configuration = {
  // ...configuration
  plugins: [
    // ...configuration.plugins
    new BridgeWebpackPlugin()
  ]
}

Typeorm

see documentation

Bridge Options

propertytyperequired
namestringyes
getTypeORMEntityasync functionyes
getAxiosInstanceasync functionno
uristring | objectno
connectionstringno
deleteToSoftbooleanno
identifierstring | symbolno
prototypeobjectno
staticobjectno
schemaobjectno
routeOptionsobjectno

name

It is used only for aesthetics of the bridge model, but it is required we want you to understand which bridge is appearing in your log.

getTypeORMEntity

We need to know which entity you are using on the back end and this is the right way that you are using the correct entity, it has to be an asynchrona call for the entity of preference always do the import of the entity within that call, so we will be sure that the extensions that make the bridge work on the front end are doing the job right.

getAxiosInstance

We need to make the request somehow and axios was chosen! So we have this option for us to understand how the requests will work, that is, if you want to use a vhost feel free, but don't forget to pass the axios service to us.

uri

Uri's are really cheating, but not! You can pass the uri as a string so it will be used in two ways :

// bridge server side method

route.get( option.uri, ...handlers ) // <- here

// bridge client side method

axios.get( option.uri ) // <- here

"But hey I'm going to use it on a sub route"

Don't worry we think about it, so the uri option can also be an object with two mandatory properties handler and request. As the name says, each one will be used in a different part of the bridge:

// bridge server side method

route.get( option.uri.handler, ...handlers )

// bridge client side method

axios.get( option.uri.request )

I almost forgot, if you don't declare this property we will use the property name.

connection

Obviously the name of the connection that we will take to make the typeorm work, if the entity is not in that connection you can expect the same errors that you would expect if it happened in the typeorm itself (final will happen in it).

deleteToSoft

A magical property, as we will take care of your basic CRUD may be that you do not want the front end to be able to delete real data, so any delete or remove will be converted to softDelete and softRemove respectively.

identifier

With this property you will be able to take your bridge wherever you are, including the options created with it.

If you pass an identifier that already exists you will receive an error, if this property is not passed you will only be able to get this information with the bridge itself.

prototype

Let's not even need to wrap it up. Every instance born with a new AnyBridge() will receive this prototype as well as classes in javascript, remembering also that the return of a bridge creation is exactly a class in javascript so you can change the prototype in flight time.

static

This property will only add static properties to the class.

schema

Validation is always important especially when it comes to api, so we chose yup for that. In this property you will be able to pass an ObjectSchema that you consider to be best suited to the needs of your entity. If you don't pass this, we will generate one with the typeorm metadata, something very basic. It is very important that you pass an ObjectSchema if you have some very specific scenarios in your database as validation of national documents, if you do not pass this schema we will return a database error, and this is certainly not what anyone wants.

routeOptions

Finally an option that you will be able to set options on the generator handlers across the bridge.

  • defaultOptions

    There are all the options of all the methods of the repository, such as save, update, delete, remove, find, etc ... They will be united with the route options passed by query params, they will be united with the tool @cookiex/deep.

  • handlers

    Routes that will be joined with the bridge route, they can only be end-of-response routes because if you have a next one without an error it will just fall into one without the preparation for the bridge, or it will not be that you are creative . The objects are separated in http methods and then immediately separated by paths with the value being a Express.RequestHandler

  • handlersMiddlewares

    They are middleware between the beginning of the specified request and the end of the response, you will be on the path between them as soon as you define any method here, and you can even replace the original. At this point, query params did not go through the parser that transforms bridge operators into typeorm operators. Then you can call them any way you like.

    To access the bridge you can of course call it statically or you can find it in the request, req.bridge.

    const handler = ( req, res, next ) => {
      req.bridge // your favorite bridge 
    }
0.0.0-0.30

3 years ago

0.0.0-0.29

3 years ago

0.0.0-0.27

3 years ago

0.0.0-0.28

3 years ago

0.0.0-0.26

3 years ago

0.0.0-0.18

3 years ago

0.0.0-0.19

3 years ago

0.0.0-0.25

3 years ago

0.0.0-0.23

3 years ago

0.0.0-0.24

3 years ago

0.0.0-0.21

3 years ago

0.0.0-0.22

3 years ago

0.0.0-0.20

3 years ago

0.0.0-0.17

3 years ago

0.0.0-0.16

3 years ago

0.0.0-0.14

3 years ago

0.0.0-0.15

3 years ago

0.0.0-0.12

3 years ago

0.0.0-0.13

3 years ago

0.0.0-0.10

3 years ago

0.0.0-0.11

3 years ago

0.0.0-0.8

3 years ago

0.0.0-0.9

3 years ago

0.0.0-0.6.10

3 years ago

0.0.0-0.6.11

3 years ago

0.0.0-0.6.4

3 years ago

0.0.0-0.6.6

3 years ago

0.0.0-0.6.5

3 years ago

0.0.0-0.6.8

3 years ago

0.0.0-0.6.17

3 years ago

0.0.0-0.6.7

3 years ago

0.0.0-0.6.18

3 years ago

0.0.0-0.6.19

3 years ago

0.0.0-0.6.9

3 years ago

0.0.0-0.6.12

3 years ago

0.0.0-0.6.13

3 years ago

0.0.0-0.6.14

3 years ago

0.0.0-0.6.15

3 years ago

0.0.0-0.6.3

3 years ago

0.0.0-0.6.2

3 years ago

0.0.0-0.6.1

3 years ago

0.0.0-0.6

3 years ago

0.0.0-0.5

3 years ago

0.0.0-0.4

3 years ago

0.0.0-0.3

3 years ago

0.0.0-0.2

3 years ago

0.0.0-0.1

3 years ago

0.0.0

3 years ago