Coder Social home page Coder Social logo

esqlate's Introduction

eSQLate

Project Purpose

eSQLate is an attempt to give small teams a quick and easy form of administration panel which is significantly more powerful than CRUD based systems but also as easy to set up.

What problem is it solving?

A lot of my work history has been based at small companies with small teams where there is enough resource to build a impressive product using great code, but it is sometimes difficult to justify investing as much time into creating administration panels which nobody other than internal employees will ever see.

There are many times I have had to delve into the database because the narrow range of operations which are available on the administration panels does not cover what I, at that moment, need to do. I don’t think this is always a problem, particularly when the project is at a very early stage but as a project grows having developers or systems administrators log into the database and change settings has some real downsides:

  • You’re taking time away from developers / systems administrators to do things which could, sometimes, be done by less technical employees.

  • Executing database operations is nearly always a bespoke operation on live data, meaning we have to be really, really careful and think things through in great detail.

  • Eventually, everyone will make a mistake, while logged into a live database the unintended effects could be disastrous.

What is it?

eSQLate interprets a simple JSON (or JSON5) file like this:

{
  "name": "product_search",
  "title": "Product Search",
  "description": "List products that include a substring",
  "parameters": [
    {
      "name": "product_name",
      "type": "string"
    }
  ],
  "statement": "\
    SELECT\n\
      product_id,\n\
      product_name,\n\
      suppliers.company_name as supplier_name,\n\
      unit_price\n\
    FROM products\n\
    LEFT JOIN suppliers on suppliers.supplier_id = products.supplier_id\n\
    WHERE LOWER(product_name) LIKE CONCAT('%', LOWER($product_name), '%')"
}

Using the above it will produce a fairly usable and reasonable web interface like what is shown below:

Simple JSON transformed into a fairly usable reasonable web interface

If users are of a nervous disposition and scared off by seeing things they don’t understand (like SQL) they can flip the toggle to convert the query based interface into a simple form.

People with a nervous disposition can hide things they don’t understand

We can specify parameters as strings, dates, datetimes, integers, selects, decimals and even use a popup to allow rich selection of a specific parameter:

Slideshow of some of the controls available

Another powerful feature is to provide the user the ability to link these simple JSON documents together. Doing this gives many possible user journeys allowing basic, but meaningful, self-service administration.

You can link documents making lots of user journeys possible

The result sets can also be downloaded as CSV files.

Tutorial - Adding a new workflow

The most simple example

About the most simple thing we can do is create a simple select of a table. This can be achieved by writing some simple JSON5 into a file:

example_definition/employee_list.json5
{
    "name": "employee_list",
    "title": "Employee List",
    "parameters": [],
    "statement": "\
        SELECT\n\
            employee_id,\n\
            last_name,\n\
            first_name,\n\
            reports_to\n\
        FROM employees"
}

The most simple thing

The most simple example - Enhanced

Taking the super simple example it is easy to make it marginally useful

example_definition/employee_list.json5
{
    "name": "employee_list",
    "title": "Employee List",
    "description": "List employee details which include a sub string",
    "parameters": [
        {
            "name": "search_string",
            "type": "string",
            "highlight_fields": ["last_name", "first_name"]
        }
    ],
    "statement": "\
        SELECT\n\
            employees.employee_id,\n\
            concat(employees.first_name, ' ', employees.last_name) as full_name,\n\
            concat(reports_to.first_name, ' ', reports_to.last_name) as reports_to\n\
        FROM employees\n\
        LEFT JOIN employees reports_to ON\n\
            reports_to.employee_id = employees.reports_to\n\
        WHERE\n\
            lower(employees.first_name) like CONCAT('%', lower($search_string) , '%') OR\n\
            lower(employees.last_name) like CONCAT('%', lower(${search_string}) , '%')\
        ",
    "statement_type": "SELECT"
}

This will find people who’s first_name or last_name includes $search_string anywhere within.

We have:

  • Defined a parameter named search_string which could also be wrote as ${search_string} if you need to be unambiguous about where the string terminates

  • Added a statement_type which really does nothing other than color the button below the query… but it goes a nice red when its a DELETE.

How does it look?

The most simple thing - enhanced

Allowing adding of employees

Taking what we know from `The most simple example'' it is trivial to transform it into an `INSERT statement, however I took the liberty of adding some comments due to the SQL separates column names from the VALUES.

example_definition/employee_add.json5
{
    "name": "employee_add",
    "title": "Add an Employee",
    "description": "Add an employee",
    "parameters": [
        { "name": "last_name", "type": "string" },
        { "name": "first_name", "type": "string" },
        { "name": "title", "type": "string" },
        { "name": "title_of_courtesy", "type": "string" },
        { "name": "birth_date", "type": "date" },
        { "name": "hire_date", "type": "date" },
        { "name": "address", "type": "string" },
        { "name": "city", "type": "string" },
        { "name": "region", "type": "string" },
        { "name": "postal_code", "type": "string" },
        { "name": "country", "type": "string" },
        { "name": "home_phone", "type": "string" },
        { "name": "extension", "type": "string" },
        { "name": "notes", "type": "string" },
        { "name": "reports_to", "type": "integer" }
    ],
    "statement": "\
        INSERT INTO employees (\n\
            last_name, first_name, title, title_of_courtesy,\n\
            birth_date, hire_date, address, city,\n\
            region, postal_code, country, home_phone,\n\
            extension, notes, reports_to\n\
        )\n\
        VALUES (\n\
            /* last_name = */ $last_name,\n\
            /* first_name = */ $first_name,\n\
            /* title = */ $title,\n\
            /* title_of_courtesy = */ $title_of_courtesy,\n\
            /* birth_date = */ $birth_date,\n\
            /* hire_date = */ $hire_date,\n\
            /* address = */ $address,\n\
            /* city = */ $city,\n\
            /* region = */ $region,\n\
            /* postal_code = */ $postal_code,\n\
            /* country = */ $country,\n\
            /* home_phone = */ $home_phone,\n\
            /* extension = */ $extension,\n\
            /* notes = */ $notes,\n\
            /* reports_to = */ $reports_to\n\
        )",
    "statement_type": "INSERT"
}

The end result looks like the below:

A very simple insert

Allowing adding of employees - who they report to - enhanced!

I dislike the way a user would have to take note of the user_id that the new employee would report to…

To fix it all we need to do is change { "name": "reports_to", "type": "integer" } into { "display_field": "full_name", "definition": "employee_list", "value_field": "employee_id", "type": "popup", "name": "reports_to" }. The final file is shown below:

Also converting the input of dates to dates is really easy (just change the "type").

example_definition/employee_add.json5
{
    "name": "employee_add",
    "title": "Add an Employee",
    "description": "Add an employee",
    "parameters": [
        { "name": "last_name", "type": "string" },
        { "name": "first_name", "type": "string" },
        { "name": "title", "type": "string" },
        { "name": "title_of_courtesy", "type": "string" },
        { "name": "birth_date", "type": "date" }, /* Changed from "string" to "date" */
        { "name": "hire_date", "type": "date" }, /* Changed from "string" to "date" */
        { "name": "address", "type": "string" },
        { "name": "city", "type": "string" },
        { "name": "region", "type": "string" },
        { "name": "postal_code", "type": "string" },
        { "name": "country", "type": "string" },
        { "name": "home_phone", "type": "string" },
        { "name": "extension", "type": "string" },
        { "name": "notes", "type": "string" },
        {
            "display_field": "full_name", /* Changed from "string" to "popup" */
            "definition": "employee_list",
            "value_field": "employee_id",
            "type": "popup",
            "name": "reports_to"
        }
    ],
    "statement": "\
        INSERT INTO employees (\n\
            last_name, first_name, title, title_of_courtesy,\n\
            birth_date, hire_date, address, city,\n\
            region, postal_code, country, home_phone,\n\
            extension, notes, reports_to\n\
        )\n\
        VALUES (\n\
            /* last_name = */ $last_name,\n\
            /* first_name = */ $first_name,\n\
            /* title = */ $title,\n\
            /* title_of_courtesy = */ $title_of_courtesy,\n\
            /* birth_date = */ $birth_date,\n\
            /* hire_date = */ $hire_date,\n\
            /* address = */ $address,\n\
            /* city = */ $city,\n\
            /* region = */ $region,\n\
            /* postal_code = */ $postal_code,\n\
            /* country = */ $country,\n\
            /* home_phone = */ $home_phone,\n\
            /* extension = */ $extension,\n\
            /* notes = */ $notes,\n\
            /* reports_to = */ $reports_to\n\
        )",
    "statement_type": "INSERT"
}

The end result is that there will be a new control shown which when clicked will open a pop-up:

Add a popup

The definitions we’ve defined so far do not have to be completely independent. It is possible to define links both on each row of the result set and above/below of the definition / form itself.

Lets first add a link from the Employee List to Employee Add. We can do this in three ways to a definition:

Links are displayed between the definition and the results:

"links": [
  { "href": "#employee_add", "text": "Add an employee" }
]

Links

Links are displayed above the definition:

"top_links": [
  { "href": "#employee_add", "text": "Add an employee" }
]

Links

This will add a row on every line of the results table. This is useful if the row denotes some information you want to use in the place which you are linking to. To do this add the following to the root of the definition:

"row_links": [
  { "href": "#employee_add?reports_to=${popup employee_id full_name}", "text": "Add Subordinate for ${full_name}" }
]

Links on a row

Hiding the ``Employee Add'' Menu Item

If you wish to hide the `Employee Add'' menu item it is simple enough. Just change the name (and filename) from `employee_add.json5 to _employee_add.json5. Beware any links that exist will also need to updated.

Installation

Docker Compose Method

If you’re just trying eSQLate out the most simple way to test it out is to use Docker Compose. There is a docker-compose.yml file right in this directory so all you’ll have to do is:

Directly on VM/Metal Method

Installation is relatively simple. All you need to do is install:

  • PostgreSQL The most awesome SQL database.

  • eSQLate Server Which is provides the API functions and does the actual database queries.

  • eSQLate Front talks to eSQLate Server and provides a web based interface to the user.

If you have a PostgreSQL server and want to run it on your local laptop you may choose to use the desktop method.

This will has the nicety of automagically picking port numbers and opening the browser once everything has started up.

  • Set up a PostgreSQL server and get the hostname, port, username and password (You may want to use docker-compose -f docker-compose-for-postgres-northwind.yml up from this repository).

  • Clone this repository with eSQLate with git clone https://github.com/forbesmyester/esqlate.git.

  • Change into the directory you checked out the code into with cd esqlate

  • Run npm install to install dependencies etc.

  • Run ./esqlate postgresql (If you used "docker-compose-for-postgres-northwind.yml" you could run ./esqlate postgresql -h 127.0.0.1 -d postgres -U postgres -W postgres).

Note
This can be run using ./esqlate mysql if you are using a MySQL server.

Running the Integration Tests

There are some basic integration tests that run using Cypress. To run them first bring up testing docker compose and then run the tests:

docker-compose -f ./docker-compose-integration.yml up

Contributors

Thank you

  • @richrd - esqlate-front: Support for showing results in Extended Display mode

  • @richrd - esqlate-front: Support for displaying JSONB

Changelog

1.0.0

Initial Release

1.0.2

Esqlate: Work on CI tests and launch script Front: Remove envsubst in esqlate-front build scripts

1.0.3

Esqlate: Improve CI tests Front: Use prePublishOnly to fix esqlate bug 6 Server Use prePublishOnly

1.0.4

Server: Fix not being able to use user_id parameter

1.1.0

Server: Support multiple databases (MySQL and PostgreSQL currently supported) Front: Support for showing JSONB fields - Thanks @richrd

1.1.1

Front: Support for showing results in Extended Display mode - Thanks @richrd

1.1.2

Server: Support parallelism for database queries (roughly connection count, but not quite).

1.1.3

Front & Server: Fix general bit-rot by updating child esqlate-* repositories.

What still needs to be done?

  • SERVER: Currently results persisted to the local disk. I plan to add an AWS S3 persistence option.

esqlate's People

Contributors

dproteus13 avatar forbesmyester 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

esqlate's Issues

Add option to show table similarly as Extended display mode in PSQL

Tables with lots of columns have to be scrolled sideways and it can become a bit cumbersome at times. It'd be nice to be able to show the table with each column & value pair on a separate line. The same as the \x option in PSQL. I'd be willing to implement this if you like.

I already have a proof of concept that's mostly based on CSS. The HTML markup doesn't require any changes except adding data-field-name={ result.fields[i].name } on the <td> elements so the column name can be shown via CSS content: attr(data-field-name);. I think the easiest way to then toggle this display mode would be by prefixing the CSS selectors for it with e.g. a extended-display class. Then we can toggle that class on some parent element to enable and disable the CSS.

What do you think?

Issue to get it up and running via docker-compose

Hi 👋

First off, very cool project! I'd like to give it a try, but I stumbled on getting this up and running via docker-compose.

I have just followed the README. Here are the steps:

  1. clone & cd to the project
  2. npm install
  3. docker-compose build && docker-compose up

In step 3, I get the following errors: (I might be missing something here. Would you mind taking a look at it?)

Step 14/14 : CMD mkdir -p public && npm run-script && npm run-script build && npm run-script start
 ---> Using cache
 ---> 7e40536b0f65
Successfully built 7e40536b0f65
Successfully tagged esqlate_front:latest
Starting esqlate_db_loader_1 ... done
Starting esqlate_reaper_1    ... done
Starting esqlate_nginx_1     ... done
Starting esqlate_db_1        ... done
Starting esqlate_front_1     ... done
Starting esqlate_server_1    ... done
Attaching to esqlate_db_loader_1, esqlate_reaper_1, esqlate_front_1, esqlate_nginx_1, esqlate_db_1, esqlate_server_1
nginx_1      | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
nginx_1      | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
nginx_1      | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
nginx_1      | 10-listen-on-ipv6-by-default.sh: error: IPv6 listen already enabled
nginx_1      | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
nginx_1      | /docker-entrypoint.sh: Configuration complete; ready for start up
server_1     | Compiling...
db_1         |
db_1         | PostgreSQL Database directory appears to contain a database; Skipping initialization
db_1         |
db_1         | 2020-10-05 13:02:20.428 UTC [1] LOG:  starting PostgreSQL 12.4 (Debian 12.4-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
db_1         | 2020-10-05 13:02:20.428 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
db_1         | 2020-10-05 13:02:20.428 UTC [1] LOG:  listening on IPv6 address "::", port 5432
db_1         | 2020-10-05 13:02:20.431 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1         | 2020-10-05 13:02:20.447 UTC [26] LOG:  database system was shut down at 2020-10-05 13:02:13 UTC
db_1         | 2020-10-05 13:02:20.452 UTC [1] LOG:  database system is ready to accept connections
front_1      | Lifecycle scripts included in esqlate-front:
front_1      |   start
front_1      |     sirv public --single --port $LISTEN_PORT
front_1      |   test
front_1      |     set -e; for FILE in ts-test/*; do ./node_modules/.bin/ts-node "$FILE"; done
front_1      |
front_1      | available via `npm run-script`:
front_1      |   autobuild
front_1      |     rollup -c -w
front_1      |   build
front_1      |     npm run-script build-templates && npm run-script build-scss && npm run-script build-ts && npm run-script build-third-party && ./node_modules/.bin/rollup -c
front_1      |   build-rollup
front_1      |     rollup -c
front_1      |   build-scss
front_1      |     node-sass src/index.scss > public/index.css
front_1      |   build-templates
front_1      |     mkdir -p public && cat src/index.tpl.html | sed "s^\${API_SERVER}^$API_SERVER^g" > public/index.html
front_1      |   build-third-party
front_1      |     mkdir -p public/node_modules && tar -C node_modules -c director/build/director.js markdown-it/dist/markdown-it.min.js | tar -C public/node_modules/ -x
front_1      |   build-ts
front_1      |     tsc && cp -R ts-build/ts-src/* src/
front_1      |   dev
front_1      |     run-p start:dev autobuild
front_1      |   prepublishOnly
front_1      |     npm run-script build
front_1      |   start:dev
front_1      |     sirv public --single --dev --port $LISTEN_PORT
front_1      |
front_1      | > [email protected] build /project
front_1      | > npm run-script build-templates && npm run-script build-scss && npm run-script build-ts && npm run-script build-third-party && ./node_modules/.bin/rollup -c
front_1      |
db_loader_1  | Skipping loading data as it already appears to be there
esqlate_db_loader_1 exited with code 0
front_1      |
front_1      | > [email protected] build-templates /project
front_1      | > mkdir -p public && cat src/index.tpl.html | sed "s^\${API_SERVER}^$API_SERVER^g" > public/index.html
front_1      |
front_1      |
front_1      | > [email protected] build-scss /project
front_1      | > node-sass src/index.scss > public/index.css
front_1      |
front_1      |
front_1      | > [email protected] build-ts /project
front_1      | > tsc && cp -R ts-build/ts-src/* src/
front_1      |
server_1     | src/MySQLQueryRunner.ts(112,44): error TS2339: Property 'name' does not exist on type 'never'.
server_1     |   The intersection 'FieldInfo & { type: string; }' was reduced to 'never' because property 'type' has conflicting types in some constituents.
server_1     | src/MySQLQueryRunner.ts(113,47): error TS2339: Property 'name' does not exist on type 'never'.
server_1     |   The intersection 'FieldInfo & { type: string; }' was reduced to 'never' because property 'type' has conflicting types in some constituents.
server_1     | src/MySQLQueryRunner.ts(113,65): error TS2339: Property 'type' does not exist on type 'never'.
server_1     |   The intersection 'FieldInfo & { type: string; }' was reduced to 'never' because property 'type' has conflicting types in some constituents.
server_1     | src/MySQLQueryRunner.ts(114,43): error TS2339: Property 'name' does not exist on type 'never'.
server_1     |   The intersection 'FieldInfo & { type: string; }' was reduced to 'never' because property 'type' has conflicting types in some constituents.
server_1     | src/MySQLQueryRunner.ts(120,20): error TS2769: No overload matches this call.
server_1     |   Overload 1 of 3, '(options: string | QueryOptions, callback?: queryCallback | undefined): Query', gave the following error.
server_1     |     Argument of type '{ sql: string; typeCast: (field: FieldInfo & {    type: string;}, next: () => void) => void; }' is not assignable to parameter of type 'string | QueryOptions'.
server_1     |       Type '{ sql: string; typeCast: (field: FieldInfo & {    type: string;}, next: () => void) => void; }' is not assignable to type 'QueryOptions'.
server_1     |         Types of property 'typeCast' are incompatible.
server_1     |           Type '(field: FieldInfo & {    type: string;}, next: () => void) => void' is not assignable to type 'boolean | ((field: UntypedFieldInfo & { type: string; length: number; string(): string; buffer(): Buffer; geometry(): GeometryType | null; }, next: () => void) => any) | undefined'.
server_1     |             Type '(field: FieldInfo & {    type: string;}, next: () => void) => void' is not assignable to type '(field: UntypedFieldInfo & { type: string; length: number; string(): string; buffer(): Buffer; geometry(): GeometryType | null; }, next: () => void) => any'.
server_1     |               Types of parameters 'field' and 'field' are incompatible.
server_1     |                 Type 'UntypedFieldInfo & { type: string; length: number; string(): string; buffer(): Buffer; geometry(): GeometryType | null; }' is not assignable to type 'never'.
server_1     |                   The intersection 'FieldInfo & { type: string; }' was reduced to 'never' because property 'type' has conflicting types in some constituents.
server_1     |   Overload 2 of 3, '(options: string | QueryOptions, values: any, callback?: queryCallback | undefined): Query', gave the following error.
server_1     |     Argument of type '{ sql: string; typeCast: (field: FieldInfo & {    type: string;}, next: () => void) => void; }' is not assignable to parameter of type 'string | QueryOptions'.
server_1     |       Type '{ sql: string; typeCast: (field: FieldInfo & {    type: string;}, next: () => void) => void; }' is not assignable to type 'QueryOptions'.
server_1     | src/MySQLQueryRunner.ts(120,26): error TS7006: Parameter 'err' implicitly has an 'any' type.
server_1     | src/nextWrap.ts(19,21): error TS2345: Argument of type '(err?: Error | undefined) => void' is not assignable to parameter of type 'NextFunction'.
server_1     |   Types of parameters 'err' and 'deferToNext' are incompatible.
server_1     |     Type '"router"' is not assignable to type 'Error | undefined'.
esqlate_server_1 exited with code 2
front_1      | ts-test/middleware.ts(81,18): error TS2571: Object is of type 'unknown'.
front_1      | ts-test/middleware.ts(85,18): error TS2571: Object is of type 'unknown'.
front_1      | ts-test/middleware.ts(97,18): error TS2571: Object is of type 'unknown'.
front_1      | npm ERR! code ELIFECYCLE
front_1      | npm ERR! errno 2
front_1      | npm ERR! [email protected] build-ts: `tsc && cp -R ts-build/ts-src/* src/`
front_1      | npm ERR! Exit status 2
front_1      | npm ERR!
front_1      | npm ERR! Failed at the [email protected] build-ts script.
front_1      | npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
front_1      |
front_1      | npm ERR! A complete log of this run can be found in:
front_1      | npm ERR!     /root/.npm/_logs/2020-10-05T13_02_27_184Z-debug.log
front_1      | npm ERR! code ELIFECYCLE
front_1      | npm ERR! errno 2
front_1      | npm ERR! [email protected] build: `npm run-script build-templates && npm run-script build-scss && npm run-script build-ts && npm run-script build-third-party && ./node_modules/.bin/rollup -c`
front_1      | npm ERR! Exit status 2
front_1      | npm ERR!
front_1      | npm ERR! Failed at the [email protected] build script.
front_1      | npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
front_1      |
front_1      | npm ERR! A complete log of this run can be found in:
front_1      | npm ERR!     /root/.npm/_logs/2020-10-05T13_02_27_208Z-debug.log
esqlate_front_1 exited with code 2

http://localhost:8800/ returns 502 (Bad Gateway)

Running the local install fails due to node-sass

I tried installing with both NPM and Yarn.

user@machine:~/Projects/esqlate$ ./esqlate --host localhost --database xxxx --user xxxx --password xxx
Server launching on 'http://localhost:3500'
Front launching on 'http://localhost:3600'

> [email protected] front /home/user/Projects/esqlate
> cd ./node_modules/esqlate-front && bash -c ' [ ! -d node_modules ] && npm install || true ' && npm run-script build && npm start


> [email protected] server /home/user/Projects/esqlate
> cd ./node_modules/esqlate-server && bash -c ' [ ! -d node_modules ] && npm install || true ' && npm run-script build && npm start


> [email protected] build /home/user/Projects/esqlate/node_modules/esqlate-server
> tsc


> [email protected] build /home/user/Projects/esqlate/node_modules/esqlate-front
> npm run-script build-templates && npm run-script build-scss && npm run-script build-ts && npm run-script build-third-party && ./node_modules/.bin/rollup -c


> [email protected] build-templates /home/user/Projects/esqlate/node_modules/esqlate-front
> mkdir -p public && cat src/index.tpl.html | sed "s^\${API_SERVER}^$API_SERVER^g" > public/index.html


> [email protected] build-scss /home/user/Projects/esqlate/node_modules/esqlate-front
> node-sass src/index.scss > public/index.css

sh: 1: node-sass: not found
npm ERR! file sh
npm ERR! code ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! syscall spawn
npm ERR! [email protected] build-scss: `node-sass src/index.scss > public/index.css`
npm ERR! spawn ENOENT
npm ERR!
npm ERR! Failed at the [email protected] build-scss script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/user/.npm/_logs/2020-01-17T16_51_46_256Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] build: `npm run-script build-templates && npm run-script build-scss && npm run-script build-ts && npm run-script build-third-party && ./node_modules/.bin/rollup -c`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/user/.npm/_logs/2020-01-17T16_51_46_266Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] front: `cd ./node_modules/esqlate-front && bash -c ' [ ! -d node_modules ] && npm install || true ' && npm run-script build && npm start`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] front script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/user/.npm/_logs/2020-01-17T16_51_46_276Z-debug.log
Front finished  with exit code 1
Stopping server
src/QueryRunner.ts(2,21): error TS7016: Could not find a declaration file for module 'pg'. '/home/user/Projects/esqlate/node_modules/pg/lib/index.js' implicitly has an 'any' type.
  Try `npm install @types/pg` if it exists or add a new declaration (.d.ts) file containing `declare module 'pg';`
src/QueryRunner.ts(3,44): error TS7016: Could not find a declaration file for module 'pg'. '/home/user/Projects/esqlate/node_modules/pg/lib/index.js' implicitly has an 'any' type.
  Try `npm install @types/pg` if it exists or add a new declaration (.d.ts) file containing `declare module 'pg';`
src/QueryRunner.ts(128,40): error TS7006: Parameter 'f' implicitly has an 'any' type.
src/QueryRunner.ts(183,17): error TS7031: Binding element 'rows' implicitly has an 'any' type.
src/middleware.ts(2,49): error TS7016: Could not find a declaration file for module 'express'. '/home/user/Projects/esqlate/node_modules/express/index.js' implicitly has an 'any' type.
  Try `npm install @types/express` if it exists or add a new declaration (.d.ts) file containing `declare module 'express';`
src/middleware.ts(4,19): error TS7016: Could not find a declaration file for module 'json5'. '/home/user/Projects/esqlate/node_modules/json5/lib/index.js' implicitly has an 'any' type.
  Try `npm install @types/json5` if it exists or add a new declaration (.d.ts) file containing `declare module 'json5';`
src/middleware.ts(371,37): error TS7006: Parameter 'err' implicitly has an 'any' type.
src/nextWrap.ts(1,87): error TS7016: Could not find a declaration file for module 'express'. '/home/user/Projects/esqlate/node_modules/express/index.js' implicitly has an 'any' type.
  Try `npm install @types/express` if it exists or add a new declaration (.d.ts) file containing `declare module 'express';`
src/persistence.ts(9,27): error TS7016: Could not find a declaration file for module 'json2csv'. '/home/user/Projects/esqlate/node_modules/json2csv/dist/json2csv.cjs.js' implicitly has an 'any' type.
  Try `npm install @types/json2csv` if it exists or add a new declaration (.d.ts) file containing `declare module 'json2csv';`
src/server.ts(3,24): error TS7016: Could not find a declaration file for module 'body-parser'. '/home/user/Projects/esqlate/node_modules/body-parser/index.js' implicitly has an 'any' type.
  Try `npm install @types/body-parser` if it exists or add a new declaration (.d.ts) file containing `declare module 'body-parser';`
src/server.ts(4,33): error TS7016: Could not find a declaration file for module 'cors'. '/home/user/Projects/esqlate/node_modules/cors/lib/index.js' implicitly has an 'any' type.
  Try `npm install @types/cors` if it exists or add a new declaration (.d.ts) file containing `declare module 'cors';`
src/server.ts(5,92): error TS7016: Could not find a declaration file for module 'express'. '/home/user/Projects/esqlate/node_modules/express/index.js' implicitly has an 'any' type.
  Try `npm install @types/express` if it exists or add a new declaration (.d.ts) file containing `declare module 'express';`
src/server.ts(8,22): error TS7016: Could not find a declaration file for module 'pg'. '/home/user/Projects/esqlate/node_modules/pg/lib/index.js' implicitly has an 'any' type.
  Try `npm install @types/pg` if it exists or add a new declaration (.d.ts) file containing `declare module 'pg';`
src/server.ts(14,19): error TS7016: Could not find a declaration file for module 'json5'. '/home/user/Projects/esqlate/node_modules/json5/lib/index.js' implicitly has an 'any' type.
  Try `npm install @types/json5` if it exists or add a new declaration (.d.ts) file containing `declare module 'json5';`
src/server.ts(210,47): error TS7006: Parameter '_req' implicitly has an 'any' type.
src/server.ts(210,53): error TS7006: Parameter 'res' implicitly has an 'any' type.
src/server.ts(210,58): error TS7006: Parameter 'next' implicitly has an 'any' type.
src/server.ts(315,19): error TS7006: Parameter 'e' implicitly has an 'any' type.
src/server.ts(319,12): error TS7006: Parameter 'lookupOid' implicitly has an 'any' type.
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! [email protected] build: `tsc`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/user/.npm/_logs/2020-01-17T16_51_49_394Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! [email protected] server: `cd ./node_modules/esqlate-server && bash -c ' [ ! -d node_modules ] && npm install || true ' && npm run-script build && npm start`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the [email protected] server script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/user/.npm/_logs/2020-01-17T16_51_49_403Z-debug.log

Feature request: Creating a scripted version

Currently you have to clone repositories and install and hope that all these (apparently, a bit fragile) setup-scripts do their job.

It would be grate if you could just create an directory full with your definitions and run npx esqlate --user .... and be up and running. From an technical standpoint that should be fairly doable by including a "bin" section into the package.json.

The UX would be top notch and would serve to solve the problem mentioned in the readme ("You’re taking time away from developers / systems administrators to do things which could, sometimes, be done by less technical employees.").

Let me know what you think about this :) Cheers

Cannot start esqlate

Hi, I have trouble running esqlate using the "Desktop Method":


> [email protected] start
> ./esqlate postgresql --host localhost --port 5432 --user postgres --password "" --database dbname

Server launch on 'http://localhost:3500'
Front launch on 'http://localhost:3600'

> [email protected] server
> npm run-script server-prepare && cd ./node_modules/esqlate-server && npm start


> [email protected] front
> npm run-script front-prepare && cd ./node_modules/esqlate-front && npm start


> [email protected] server-prepare
> cd ./node_modules/esqlate-server && bash -c ' [ ! -d node_modules ] && npm install || true '


> [email protected] front-prepare
> cd ./node_modules/esqlate-front && bash -c ' [ ! -d node_modules ] && npm install || true ' && npm run-script build-templates

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/rollup
npm ERR!   dev rollup@"^1.27.3" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer rollup@"^2.0.0" from [email protected]
npm ERR! node_modules/rollup-plugin-terser
npm ERR!   dev rollup-plugin-terser@"^7.0.2" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR! 
npm ERR! See /home/philipp/.npm/eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/philipp/.npm/_logs/2021-06-30T09_20_27_146Z-debug.log

> [email protected] build-templates
> mkdir -p public && cat src/index.tpl.html | sed "s^\${API_SERVER}^$API_SERVER^g" > public/index.html


> [email protected] start
> ./node_modules/.bin/sirv public --single --port $LISTEN_PORT

sh: Zeile 1: ./node_modules/.bin/sirv: Datei oder Verzeichnis nicht gefunden
Front finished  with exit code 127
Stopping server
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/pg
npm ERR!   pg@"^7.12.1" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer pg@"^8" from [email protected]
npm ERR! node_modules/pg-cursor
npm ERR!   pg-cursor@"^2.0.0" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR! 
npm ERR! See /home/philipp/.npm/eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/philipp/.npm/_logs/2021-06-30T09_20_28_131Z-debug.log

> [email protected] start
> node dist/server.js

/home/philipp/git//esqlate/definition

docker-compose.yml file or setup steps in README.md show wrong path

In the Setup instuctions for setup using docker-compose you have a command to clone the esqlate-server in the subdirectory "esqlate-server".

However, the included dockerfile is expecting this to be at "./node-modules/esqlate-server" instead.

Either the docker-compose.yml file or the Readme should be modified here.

How do you handle authentication?

I’m impressed by your tool and would love to use it at our company. Thanks for publishing it!

How do you authenticate/authorize access to the admin panel published via esqlate? Can you offer pointers?

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.