Giter Site home page Giter Site logo

philipskinner / elemental-lowcode Goto Github PK

View Code? Open in Web Editor NEW
111.0 6.0 15.0 8.25 MB

Elemental lowcode development platform.

License: MIT License

JavaScript 90.63% HTML 7.04% Shell 0.17% EJS 1.46% Dockerfile 0.08% SCSS 0.63%
lowcode rulesets storage low-code-development-platform low-code low-code-platform api-server api-rest

elemental-lowcode's Introduction

Elemental logo

Elemental low-code platform

Build Status Coverage Status Codacy Badge GitHub issues GitHub forks GitHub stars PRs Welcome

A standards based, open low-code development platform built on nodejs with the ability to fallback to writing raw nodejs code when the provided tools cannot solve your problems.

Currently ships with:

  • JSON Schema defined RESTful APIs
  • Simple async messaging queues
  • Integrations to external systems
  • API builder
  • Rulesets builder
  • Interface/website builder
  • OIDC/OAuth2.0 Identity Provider & Identity Management
  • Blob storage service

Table of Contents

Installation

Installation can done using the prebuilt docker image or using the latest code from master.

Docker

To use the docker image you'll need to boot a SQL server and configure the system:

services:
  elemental:
    image: philipskinner/elemental:latest
    environment:
      MYSQL_CONNECTION_STRING: "mysql://root:password@mysql:3306/db"
      INITIAL_CLIENT_ID: admin
      INITIAL_CLIENT_SECRET: admin-secret
      INITIAL_CLIENT_SCOPES: "openid roles offline_access"
      INITIAL_CLIENT_AUTH_REDIRECT: http://admin.elementalsystem.org/auth
      INITIAL_CLIENT_LOGOUT_REDIRECT: http://admin.elementalsystem.org
      INITIAL_ROLES: "system_admin"
      INITIAL_USER_USERNAME: [email protected]
      INITIAL_USER_PASSWORD: Password1!
      INITIAL_USER_ROLE: system_admin
      ADMIN_CLIENT_ID: admin
      ADMIN_CLIENT_SECRET: admin-secret
    ports:
      - 80:80
    depends_on:
      - mysql      
    networks:
      - all  

  mysql:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: password
    volumes:
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - all

networks:
  all:

; then open a browser and point it at (http://admin.elementalsystem.org).

The default administration login details are configurable using the INITIAL_USER_USERNAME and INITIAL_USER_PASSWORD env vars. If you used the docker-compose setup above you'll want to use:

The docker image uses several pre-defined hostnames for the service, each of which resolves to 127.0.0.1:

From source

Follow these steps to build and run from source:

$> git clone https://github.com/PhilipSkinner/elemental-lowcode.git elemental-lowcode
$> cd elemental-lowcode && ./setup.sh
$> ./start.sh

You can directly run the kernel by executing the main.js file within the kernel directory:

$> cd src/service.kernel
$> node main.js

The following usage options are available when you do this:

Usage: node main.js [OPTIONS]

Options:
	--sources [SOURCE_DIR]		Sets the directory where your Elemental application
                                        source code lives.

The admin interface will attempt to open on http://localhost:8002. Use the following default credentials:

Database support

Elemental supports persistence of:

  • Authentication details
  • Data types
  • Message queues
  • Website session state

; with a selection of storage options. These storage options are:

  • SQL:
    • sqlite
    • postgres
    • mysql
    • mariadb
    • mssql

Documentation

Documentation is available within Elemental:

In app documentation

; or you can read it on the Elemental Documentation website.

Examples

Examples can be found in the elemental-examples repository.

To use the examples clone the repository locally then set Elemental to run from a specific example directory:

$> git clone https://github.com/PhilipSkinner/elemental-lowcode.git elemental-lowcode
$> git clone https://github.com/PhilipSkinner/elemental-examples.git elemental-examples
$> cd elemental-lowcode && ./setup.sh
$> cd kernel && node main.js --sources ../../elemental-examples/todo

; then open the admin interface on http://localhost:8002. Each example comes with an admin user with the following credentials:

  • Username: admin
  • Password: admin

Hosting

The recommended approach for deploying your application is to build on the dockerhub image. The following is an example dockerfile that builds and configures Elemental with a set of Elemental applications:

FROM philipskinner/elemental:master

#set dir
WORKDIR /var/elemental

#copy our project sources
COPY my-sources /var/elemental/service.kernel/.sources

#set environment
COPY nginx.conf /etc/nginx
ENV KERNEL_HOST="http://kernel.mysite.com"
ENV ADMIN_HOST="http://admin.mysite.com"
ENV API_HOST="http://api.mysite.com"
ENV INTEGRATION_HOST="http://integration.mysite.com"
ENV INTERFACE_HOST="http://interface.mysite.com"
ENV STORAGE_HOST="http://storage.mysite.com"
ENV RULES_HOST="http://rules.mysite.com"
ENV IDENTITY_HOST="http://identity.mysite.com"
ENV QUEUE_HOST="http://queues.mysite.com"
ENV BLOB_HOST="http://blobs.mysite.com"

#run our app
CMD ["./docker-start.sh"]

If you want to run the system outside of a docker container you must set the following environmental variables on your system:

  • KERNEL_HOST
  • ADMIN_HOST
  • API_HOST
  • INTEGRATION_HOST
  • INTERFACE_HOST
  • STORAGE_HOST
  • RULES_HOST
  • IDENTITY_HOST
  • QUEUE_HOST
  • BLOB_HOST

Each of these needs to be a valid hostname that resolves to the relevant Elemental service.

Secrets

Elemental has built in support for secrets management. Secrets can be configured within your applications and then the secrets definition can be deployed on a per environment basis - outside of version control of your main application.

Secrets can be scoped for global access or restricted to a specific Elemental subsystem.

To deploy secrets you need to copy a JSON file for each secret into the kernel/.secrets directory. Each JSON file should follow this format:

{
    "value": "my-secret-value"
}

; where the filename is secret-name.secret.json within the kernel/.secrets directory. You can copy these at build time within your dockerfile:

COPY my-secrets/*.json /var/elemental/kernel/.secrets/

Contributing

Contributions, code or otherwise, are very welcome!

To contribute a code change:

  1. Fork the master branch
  2. Carry out your code changes
  3. Run the unit tests - ./test.sh
  4. Submit a pull request following pull request template

To contribute a none code change raise a ticket on the original repository.

Authors

Philip Skinner
Philip Skinner

Support

Raise a ticket on the repository describing the issue in as much detail as possible.

Alternatively reach out to [email protected] and I'll reply as soon as I can.

Links

More information about Elemental can be found at:

The following are standards that Elemental attempts to follow:

Elemental relies upon several other projects, notable ones are:

License

Elemental is licensed under the terms of the MIT License and is free to use and free to modify.

elemental-lowcode's People

Contributors

dependabot[bot] avatar philipskinner 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

elemental-lowcode's Issues

Etag support on storage entities

Ensure that etags are supported on storage entities, supporting both the response of the version with the etag header and the use of if-match headers on:

  • GET
  • POST
  • PUT
  • PATCH
  • DELETE

On modification operations this is to deal with modification conflicts and should return a 409 Conflict status code.

On fetching a single resource, the if-match header can be used to determine if the resource has changed - if it has not then a 304 Not Modified is to be returned.

The use of * as the if-match header value means either "ignore the version identifier" or "fetch the latest" - depending upon the incoming HTTP request method.

If the if-match header is omitted then it is to be as though the client sent the value * within it.

Publish/build container images

Allow the system to build a container image (docker etc). This needs to run from the command line so it can be run as part of a CI process to generate container images for further deployments.

Websites - read auth client config

The websites service has a hardcoded client id & secret - this is just work in progress.

Complete the websites service so that it can read its relevant auth client config and can configure itself for user & client auth.

Data types - reader/writer/deletion roles

Allow developers to define reader/writer/deletion roles for each collection instead of them being defined automatically for the user.

If no roles are defined by the user, then the defaults (as is) should be defined. The user must be able to define more than 1 role for each.

Documentation on website

Ensure that the documentation that ships with the system can be read on the website for the project.

IoC Services

Right now, the only system with an IoC container is the API system.

When the messaging & scheduling systems are completed, these will require injectable services aswell.

These should be shared between all three of these systems, instead of being defined in each one.

Abstract these out into a new services registry and ensure that the same IoC container can be used in each place. Ensure there is a simple lifecycle - like the current API IoC container.

Tutorials

Complete basic tutorials that cover how to build:

  • A todo list app
  • A blogging website
  • A ticketing system

Conditionals adding on UI

When adding a conditional, it needs to fill the object with the logical operator and statement props otherwise the model does not bind.

Add support for git on app sources

Allow the user to commit their application changes to a git repository.

The admin will need to be connected to a git repo and/or the admin can be pointed at a specific directory which the kernel will load the sources from. Said directory, if under git version control, should be detected and committing of modifications should be made available via kernel API endpoints to the admin interface.

Confirmation for object deletion

Ensure that all deletion operations on the admin have a confirmation dialog that confirms the action before it is carried out - right now you don't get a second chance.

Command line tool - setup intial admin account

Setting up an initial administrative account on the system is currently part of the IdP - every newly registered user right now is a system admin!

This needs to be removed and replaced with a command line helper that sets this up as a one time task.

Async system (messaging)

Add a basic async messaging system that fronts a pubsub style API for each message queue - where tasks can be submitted and results are tracked within a result object.

Create a runtime where each message type has a single controller that can be used to action an incoming message.

Ensure that any design choices do not preclude the ability to include a basic IoC container with injectable services.

Admin homepage information screen

Complete the homepage information screen so it gives a system overview and relevant information to the developer.

A placeholder exists at the moment, complete it so it shows real information and add any other relevant information.

XML/CSV & other content types on integrations outgoing response

Enable the automatic conversion of XML & CSV responses from outgoing request responses.

Allow users to configure the integration to return the raw response buffer into the transformation mechanism so other data formats can be handled by the users directly.

Authentication for outbound integrations requests

Allow outbound integrations requests to support the HTTP authentication types within the subtasks.

Each subtask covers how each authentication mechanism should work.

Every solution must require minimal configuration from the user.

All configuration must be held within the {{request}} configuration within the integration config document, and should follow this structure:

{
  "request": {
    "uri": "https://jsonplaceholder.typicode.com/posts/$.body.id",
    "method": "get",
    "authentication" : {
      "mechanism" : "http_basic",
      "config" : {
        "username" : "my-username",
        "password" : "$.secret.name"
      }
    }
  }
}

Secrets can be used for resolving values the user may not want to disclose within their integration configuration.

POST/PUT/DELETE/PATCH on incoming integration requests

Add support for the following incoming HTTP request methods:

  • POST
  • PUT
  • PATCH
  • DELETE

For the methods that require a body to be defined, update the integration definition so that it supports an incoming body definition in the form of a JSON schema definition.

This should be used for verifying the body sent to the integration endpoint.

Here is an example integration configuration showing how this should look:

{
  "name": "examplePostRequest",
  "description": "Get a single post from our example third party system.",
  "method": "post",
  "body": {
    "type": "object",
    "properties": {
      "id" : {
        "type" : "integer"
      }      
    }
  },  
  "request": {
    "uri": "https://jsonplaceholder.typicode.com/posts/$.body.id",
    "method": "get",
    "schema": {
      "type": "JSON",
      "value": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "integer"
          },
          "id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "body": {
            "type": "string"
          }
        },
        "required": [
          "userId",
          "id",
          "title",
          "body"
        ]
      }
    }
  },
  "transformer": "(input) => { return input; }"
}

Filtering on storage service

Need to be able to filter records in the storage service by any value held within the document in the type.

This should be done by supporting query parameters in the form:

filter_$.path.to.variable=value to find

; which would become:

filter_%24.path.to.variable=value%20to%find

; when URI encoded. This allows for JSON path identification of the values to filter by the value(s) given - note! This should support multiple values aswell.

Allowed children on editor

Ensure that only correct children can be added to an element - automatically filter the tags on the left to remove invalid tag types based upon the currently selected object.

Add a new [+] button in the children area that opens a dialog and allows the user to select from one of the supported child elements.

Scheduled processes

Create a new system that allows for scheduled processes to be run every x number of seconds, minutes, hours, days, weeks, months, years etc.

Each of these processes should have a simple function behind it.

Ensure that any design taken allows for an IoC container with injectable services.

Website tag packs

Allow for reusable tag packs to be constructed for websites.

These provide reusable tags across website instances.

Ensure that there are a set of default custom tags included in the system, including:

  • Bootstrap default components
  • GDS default components

Ability to import/export apps

Add a system into the administration that allows the import and export of tarballs containing application configuration.

Integrations - definition of roles

Allow developers to define access roles within an integration. If the developer specifies no roles then the system generated ones are used automatically.

Run behind loadbalancer

Carry out the relevant changes that allow the system to run behind a collection of different domains and a load balancer, or web server doing reverse proxying.

Website - path secure flag

Right now a website path can be assigned a role that is required to access a path.

This doesn't support paths where we want them to be secure, but we do not require any particular role to access - the user simple needs to be authenticated.

Add a new boolean flag onto each path that marks it as secure.

Change the admin to include this flag, and to only show the security (or role name entry) field when it is checked.

Ensure that the website instance knows how to enforce this security on the paths.

API - access roles

Allow roles to be configured for every API endpoint. If the developer does not define a role then the system defaults are applied automatically.

Website static resources

Allow websites to contain static resources within them.

They should be stored within a special folder for the website and hosted upon the url:

http://host/websitename/static

; using the static hosting provider within express.

The administration needs to allow these to be uploaded and saved to disk - it should also allow the user to copy the absolute path to the resource so they can be referenced easily within views, and allow the user to click a link to view the resource on the website.

Set property value with statement

Allow statements to be provided to replace property values, using variables etc.

For example:

text : "$.bag.itemText"

At the moment the only way to do this is in source mode.

Progressive enhancement - website events

Automatically progressively enhance pages so that they can behave like a SPA, with partial re-renders based upon new routes being accessed and events being triggered.

Sources folder

Allow the sources folder to be controlled with a command line argument when starting the kernel.

Add in a setup phase that ensures that all services source directories are created on boot.

Add unit tests & coverage

  1. Should execute via npm run test within each project
  2. Should be jasmine based
  3. Should report coverage on a per service basis
  4. Needs a script at the root level to run all tests

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.