Merge branch 'develop' of github.com:Budibase/budibase into feature/rate-limiting
This commit is contained in:
commit
1751ebf6ca
30 changed files with 472 additions and 355 deletions
11
.github/workflows/deploy-cloud.yaml
vendored
11
.github/workflows/deploy-cloud.yaml
vendored
|
@ -38,6 +38,17 @@ jobs:
|
||||||
fi
|
fi
|
||||||
echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
|
echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Tag and release Proxy service docker image
|
||||||
|
run: |
|
||||||
|
docker login -u $DOCKER_USER -p $DOCKER_PASSWORD
|
||||||
|
yarn build:docker:proxy:prod
|
||||||
|
docker tag budibase/proxy:$release_tag budibase/proxy:$PROD_TAG
|
||||||
|
docker push budibase/proxy:$PROD_TAG
|
||||||
|
env:
|
||||||
|
DOCKER_USER: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
DOCKER_PASSWORD: ${{ secrets.DOCKER_API_KEY }}
|
||||||
|
PROD_TAG: k8s
|
||||||
|
|
||||||
- name: Configure AWS Credentials
|
- name: Configure AWS Credentials
|
||||||
uses: aws-actions/configure-aws-credentials@v1
|
uses: aws-actions/configure-aws-credentials@v1
|
||||||
with:
|
with:
|
||||||
|
|
12
.github/workflows/deploy-preprod.yml
vendored
12
.github/workflows/deploy-preprod.yml
vendored
|
@ -23,12 +23,24 @@ jobs:
|
||||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
aws-region: eu-west-1
|
aws-region: eu-west-1
|
||||||
|
|
||||||
|
|
||||||
- name: Get the latest budibase release version
|
- name: Get the latest budibase release version
|
||||||
id: version
|
id: version
|
||||||
run: |
|
run: |
|
||||||
release_version=$(cat lerna.json | jq -r '.version')
|
release_version=$(cat lerna.json | jq -r '.version')
|
||||||
echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
|
echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Tag and release Proxy service docker image
|
||||||
|
run: |
|
||||||
|
docker login -u $DOCKER_USER -p $DOCKER_PASSWORD
|
||||||
|
yarn build:docker:proxy:preprod
|
||||||
|
docker tag budibase/proxy:$release_tag budibase/proxy:$PREPROD_TAG
|
||||||
|
docker push budibase/proxy:$PREPROD_TAG
|
||||||
|
env:
|
||||||
|
DOCKER_USER: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
DOCKER_PASSWORD: ${{ secrets.DOCKER_API_KEY }}
|
||||||
|
PREPROD_TAG: k8s-preprod
|
||||||
|
|
||||||
- name: Pull values.yaml from budibase-infra
|
- name: Pull values.yaml from budibase-infra
|
||||||
run: |
|
run: |
|
||||||
curl -H "Authorization: token ${{ secrets.GH_PERSONAL_TOKEN }}" \
|
curl -H "Authorization: token ${{ secrets.GH_PERSONAL_TOKEN }}" \
|
||||||
|
|
|
@ -19,13 +19,7 @@ http {
|
||||||
tcp_nodelay on;
|
tcp_nodelay on;
|
||||||
server_tokens off;
|
server_tokens off;
|
||||||
types_hash_max_size 2048;
|
types_hash_max_size 2048;
|
||||||
{{#if compose}}
|
resolver {{ resolver }} valid=10s ipv6=off;
|
||||||
resolver 127.0.0.11 ipv6=off;
|
|
||||||
{{/if}}
|
|
||||||
{{#if k8s}}
|
|
||||||
resolver kube-dns.kube-system.svc.cluster.local valid=10s;
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
|
|
||||||
# buffering
|
# buffering
|
||||||
client_body_buffer_size 1K;
|
client_body_buffer_size 1K;
|
||||||
|
|
|
@ -1,145 +0,0 @@
|
||||||
user nginx;
|
|
||||||
error_log /var/log/nginx/error.log debug;
|
|
||||||
pid /var/run/nginx.pid;
|
|
||||||
worker_processes auto;
|
|
||||||
worker_rlimit_nofile 33282;
|
|
||||||
|
|
||||||
events {
|
|
||||||
worker_connections 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
http {
|
|
||||||
limit_req_zone $binary_remote_addr zone=ratelimit:10m rate=20r/s;
|
|
||||||
include /etc/nginx/mime.types;
|
|
||||||
default_type application/octet-stream;
|
|
||||||
charset utf-8;
|
|
||||||
sendfile on;
|
|
||||||
tcp_nopush on;
|
|
||||||
tcp_nodelay on;
|
|
||||||
server_tokens off;
|
|
||||||
types_hash_max_size 2048;
|
|
||||||
|
|
||||||
# buffering
|
|
||||||
client_body_buffer_size 1K;
|
|
||||||
client_header_buffer_size 1k;
|
|
||||||
client_max_body_size 1k;
|
|
||||||
ignore_invalid_headers off;
|
|
||||||
|
|
||||||
|
|
||||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
|
||||||
'$status $body_bytes_sent "$http_referer" '
|
|
||||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
|
||||||
|
|
||||||
map $http_upgrade $connection_upgrade {
|
|
||||||
default "upgrade";
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 10000 default_server;
|
|
||||||
listen [::]:10000 default_server;
|
|
||||||
server_name _;
|
|
||||||
client_max_body_size 1000m;
|
|
||||||
ignore_invalid_headers off;
|
|
||||||
proxy_buffering off;
|
|
||||||
port_in_redirect off;
|
|
||||||
|
|
||||||
# Security Headers
|
|
||||||
add_header X-Frame-Options SAMEORIGIN always;
|
|
||||||
add_header X-Content-Type-Options nosniff always;
|
|
||||||
add_header X-XSS-Protection "1; mode=block" always;
|
|
||||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.budi.live https://js.intercomcdn.com https://widget.intercom.io; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://fonts.googleapis.com https://rsms.me; object-src 'none'; base-uri 'self'; connect-src 'self' https://api-iam.intercom.io https://app.posthog.com wss://nexus-websocket-a.intercom.io; font-src 'self' data: https://cdn.jsdelivr.net https://fonts.gstatic.com https://rsms.me; frame-src 'self'; img-src http: https: data:; manifest-src 'self'; media-src 'self'; worker-src 'none';" always;
|
|
||||||
|
|
||||||
location /app {
|
|
||||||
proxy_pass http://app-service:4002;
|
|
||||||
rewrite ^/app/(.*)$ /$1 break;
|
|
||||||
}
|
|
||||||
|
|
||||||
location = / {
|
|
||||||
port_in_redirect off;
|
|
||||||
proxy_pass http://app-service:4002;
|
|
||||||
}
|
|
||||||
|
|
||||||
location = /v1/update {
|
|
||||||
proxy_pass http://watchtower-service:8080;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /builder/ {
|
|
||||||
port_in_redirect off;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_pass http://app-service:4002;
|
|
||||||
}
|
|
||||||
|
|
||||||
location ~ ^/(builder|app_) {
|
|
||||||
port_in_redirect off;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_pass http://app-service:4002;
|
|
||||||
}
|
|
||||||
|
|
||||||
location ~ ^/api/(system|admin|global)/ {
|
|
||||||
proxy_pass http://worker-service:4003;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /worker/ {
|
|
||||||
proxy_pass http://worker-service:4003;
|
|
||||||
rewrite ^/worker/(.*)$ /$1 break;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /api/ {
|
|
||||||
# calls to the API are rate limited with bursting
|
|
||||||
limit_req zone=ratelimit burst=20 nodelay;
|
|
||||||
|
|
||||||
# 120s timeout on API requests
|
|
||||||
proxy_read_timeout 120s;
|
|
||||||
proxy_connect_timeout 120s;
|
|
||||||
proxy_send_timeout 120s;
|
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
|
|
||||||
proxy_pass http://app-service:4002;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /db/ {
|
|
||||||
proxy_pass http://couchdb-service:5984;
|
|
||||||
rewrite ^/db/(.*)$ /$1 break;
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
|
|
||||||
proxy_connect_timeout 300;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Connection "";
|
|
||||||
chunked_transfer_encoding off;
|
|
||||||
proxy_pass http://minio-service:9000;
|
|
||||||
}
|
|
||||||
|
|
||||||
client_header_timeout 60;
|
|
||||||
client_body_timeout 60;
|
|
||||||
keepalive_timeout 60;
|
|
||||||
|
|
||||||
# gzip
|
|
||||||
gzip on;
|
|
||||||
gzip_vary on;
|
|
||||||
gzip_proxied any;
|
|
||||||
gzip_comp_level 6;
|
|
||||||
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "1.0.79-alpha.7",
|
"version": "1.0.79-alpha.9",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
|
|
|
@ -47,9 +47,9 @@
|
||||||
"build:specs": "lerna run specs",
|
"build:specs": "lerna run specs",
|
||||||
"build:docker": "lerna run build:docker && npm run build:docker:proxy:compose && cd hosting/scripts/linux/ && ./release-to-docker-hub.sh $BUDIBASE_RELEASE_VERSION && cd -",
|
"build:docker": "lerna run build:docker && npm run build:docker:proxy:compose && cd hosting/scripts/linux/ && ./release-to-docker-hub.sh $BUDIBASE_RELEASE_VERSION && cd -",
|
||||||
"build:docker:proxy": "docker build hosting/proxy -t proxy-service",
|
"build:docker:proxy": "docker build hosting/proxy -t proxy-service",
|
||||||
"build:docker:proxy:compose": "lerna run generate:proxy:compose && npm run build:docker:proxy",
|
"build:docker:proxy:compose": "node scripts/proxy/generateProxyConfig compose && npm run build:docker:proxy",
|
||||||
"build:docker:proxy:preprod": "lerna run generate:proxy:preprod && npm run build:docker:proxy",
|
"build:docker:proxy:preprod": "node scripts/proxy/generateProxyConfig preprod && npm run build:docker:proxy",
|
||||||
"build:docker:proxy:prod": "lerna run generate:proxy:prod && npm run build:docker:proxy",
|
"build:docker:proxy:prod": "node scripts/proxy/generateProxyConfig prod && npm run build:docker:proxy",
|
||||||
"build:docker:selfhost": "lerna run build:docker && cd hosting/scripts/linux/ && ./release-to-docker-hub.sh latest && cd -",
|
"build:docker:selfhost": "lerna run build:docker && cd hosting/scripts/linux/ && ./release-to-docker-hub.sh latest && cd -",
|
||||||
"build:docker:develop": "node scripts/pinVersions && lerna run build:docker && npm run build:docker:proxy:compose && cd hosting/scripts/linux/ && ./release-to-docker-hub.sh develop && cd -",
|
"build:docker:develop": "node scripts/pinVersions && lerna run build:docker && npm run build:docker:proxy:compose && cd hosting/scripts/linux/ && ./release-to-docker-hub.sh develop && cd -",
|
||||||
"build:docker:airgap": "node hosting/scripts/airgapped/airgappedDockerBuild",
|
"build:docker:airgap": "node hosting/scripts/airgapped/airgappedDockerBuild",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/backend-core",
|
"name": "@budibase/backend-core",
|
||||||
"version": "1.0.79-alpha.7",
|
"version": "1.0.79-alpha.9",
|
||||||
"description": "Budibase backend core libraries used in server and worker",
|
"description": "Budibase backend core libraries used in server and worker",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/bbui",
|
"name": "@budibase/bbui",
|
||||||
"description": "A UI solution used in the different Budibase projects.",
|
"description": "A UI solution used in the different Budibase projects.",
|
||||||
"version": "1.0.79-alpha.7",
|
"version": "1.0.79-alpha.9",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"svelte": "src/index.js",
|
"svelte": "src/index.js",
|
||||||
"module": "dist/bbui.es.js",
|
"module": "dist/bbui.es.js",
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@adobe/spectrum-css-workflow-icons": "^1.2.1",
|
"@adobe/spectrum-css-workflow-icons": "^1.2.1",
|
||||||
"@budibase/string-templates": "^1.0.79-alpha.7",
|
"@budibase/string-templates": "^1.0.79-alpha.9",
|
||||||
"@spectrum-css/actionbutton": "^1.0.1",
|
"@spectrum-css/actionbutton": "^1.0.1",
|
||||||
"@spectrum-css/actiongroup": "^1.0.1",
|
"@spectrum-css/actiongroup": "^1.0.1",
|
||||||
"@spectrum-css/avatar": "^3.0.2",
|
"@spectrum-css/avatar": "^3.0.2",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/builder",
|
"name": "@budibase/builder",
|
||||||
"version": "1.0.79-alpha.7",
|
"version": "1.0.79-alpha.9",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -65,10 +65,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "^1.0.79-alpha.7",
|
"@budibase/bbui": "^1.0.79-alpha.9",
|
||||||
"@budibase/client": "^1.0.79-alpha.7",
|
"@budibase/client": "^1.0.79-alpha.9",
|
||||||
"@budibase/frontend-core": "^1.0.79-alpha.7",
|
"@budibase/frontend-core": "^1.0.79-alpha.9",
|
||||||
"@budibase/string-templates": "^1.0.79-alpha.7",
|
"@budibase/string-templates": "^1.0.79-alpha.9",
|
||||||
"@sentry/browser": "5.19.1",
|
"@sentry/browser": "5.19.1",
|
||||||
"@spectrum-css/page": "^3.0.1",
|
"@spectrum-css/page": "^3.0.1",
|
||||||
"@spectrum-css/vars": "^3.0.1",
|
"@spectrum-css/vars": "^3.0.1",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/cli",
|
"name": "@budibase/cli",
|
||||||
"version": "1.0.79-alpha.7",
|
"version": "1.0.79-alpha.9",
|
||||||
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/client",
|
"name": "@budibase/client",
|
||||||
"version": "1.0.79-alpha.7",
|
"version": "1.0.79-alpha.9",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"module": "dist/budibase-client.js",
|
"module": "dist/budibase-client.js",
|
||||||
"main": "dist/budibase-client.js",
|
"main": "dist/budibase-client.js",
|
||||||
|
@ -19,9 +19,9 @@
|
||||||
"dev:builder": "rollup -cw"
|
"dev:builder": "rollup -cw"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "^1.0.79-alpha.7",
|
"@budibase/bbui": "^1.0.79-alpha.9",
|
||||||
"@budibase/frontend-core": "^1.0.79-alpha.7",
|
"@budibase/frontend-core": "^1.0.79-alpha.9",
|
||||||
"@budibase/string-templates": "^1.0.79-alpha.7",
|
"@budibase/string-templates": "^1.0.79-alpha.9",
|
||||||
"@spectrum-css/button": "^3.0.3",
|
"@spectrum-css/button": "^3.0.3",
|
||||||
"@spectrum-css/card": "^3.0.3",
|
"@spectrum-css/card": "^3.0.3",
|
||||||
"@spectrum-css/divider": "^1.0.3",
|
"@spectrum-css/divider": "^1.0.3",
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/frontend-core",
|
"name": "@budibase/frontend-core",
|
||||||
"version": "1.0.79-alpha.7",
|
"version": "1.0.79-alpha.9",
|
||||||
"description": "Budibase frontend core libraries used in builder and client",
|
"description": "Budibase frontend core libraries used in builder and client",
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"svelte": "src/index.js",
|
"svelte": "src/index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "^1.0.79-alpha.7",
|
"@budibase/bbui": "^1.0.79-alpha.9",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"svelte": "^3.46.2"
|
"svelte": "^3.46.2"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/server",
|
"name": "@budibase/server",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "1.0.79-alpha.7",
|
"version": "1.0.79-alpha.9",
|
||||||
"description": "Budibase Web Server",
|
"description": "Budibase Web Server",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -21,9 +21,6 @@
|
||||||
"dev:stack:down": "node scripts/dev/manage.js down",
|
"dev:stack:down": "node scripts/dev/manage.js down",
|
||||||
"dev:stack:nuke": "node scripts/dev/manage.js nuke",
|
"dev:stack:nuke": "node scripts/dev/manage.js nuke",
|
||||||
"dev:builder": "yarn run dev:stack:up && nodemon",
|
"dev:builder": "yarn run dev:stack:up && nodemon",
|
||||||
"generate:proxy:compose": "node scripts/proxy/generateProxyConfig compose",
|
|
||||||
"generate:proxy:preprod": "node scripts/proxy/generateProxyConfig preprod",
|
|
||||||
"generate:proxy:prod": "node scripts/proxy/generateProxyConfig prod",
|
|
||||||
"format": "prettier --config ../../.prettierrc.json 'src/**/*.ts' --write",
|
"format": "prettier --config ../../.prettierrc.json 'src/**/*.ts' --write",
|
||||||
"specs": "node specs/generate.js && openapi-typescript specs/openapi.yaml --output src/definitions/openapi.ts",
|
"specs": "node specs/generate.js && openapi-typescript specs/openapi.yaml --output src/definitions/openapi.ts",
|
||||||
"lint": "eslint --fix src/",
|
"lint": "eslint --fix src/",
|
||||||
|
@ -74,9 +71,9 @@
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apidevtools/swagger-parser": "^10.0.3",
|
"@apidevtools/swagger-parser": "^10.0.3",
|
||||||
"@budibase/backend-core": "^1.0.79-alpha.7",
|
"@budibase/backend-core": "^1.0.79-alpha.9",
|
||||||
"@budibase/client": "^1.0.79-alpha.7",
|
"@budibase/client": "^1.0.79-alpha.9",
|
||||||
"@budibase/string-templates": "^1.0.79-alpha.7",
|
"@budibase/string-templates": "^1.0.79-alpha.9",
|
||||||
"@bull-board/api": "^3.7.0",
|
"@bull-board/api": "^3.7.0",
|
||||||
"@bull-board/koa": "^3.7.0",
|
"@bull-board/koa": "^3.7.0",
|
||||||
"@elastic/elasticsearch": "7.10.0",
|
"@elastic/elasticsearch": "7.10.0",
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
|
|
||||||
To install oracle express edition simply run `docker-compose up`
|
To install oracle express edition simply run `docker-compose up`
|
||||||
|
|
||||||
- A single instance pluggable database (PDB) will be created named `xepdb`
|
- A single instance pluggable database (PDB) will be created named `xepdb1`
|
||||||
- The default password is configured in the compose file as `oracle`
|
- The default password is configured in the compose file as `oracle`
|
||||||
- The `system`, `sys` and `pdbadmin` users all share this password
|
- The `system` and `pdbadmin` users share this password
|
||||||
|
|
||||||
## Instant Client
|
## Instant Client
|
||||||
|
|
||||||
|
|
|
@ -5,5 +5,8 @@ export interface DatasourcePlus extends IntegrationBase {
|
||||||
tables: Record<string, Table>
|
tables: Record<string, Table>
|
||||||
schemaErrors: Record<string, string>
|
schemaErrors: Record<string, string>
|
||||||
|
|
||||||
|
// if the datasource supports the use of bindings directly (to protect against SQL injection)
|
||||||
|
// this returns the format of the identifier
|
||||||
|
getBindingIdentifier(): string
|
||||||
buildSchema(datasourceId: string, entities: Record<string, Table>): any
|
buildSchema(datasourceId: string, entities: Record<string, Table>): any
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,10 @@ import {
|
||||||
} from "../definitions/datasource"
|
} from "../definitions/datasource"
|
||||||
import { OAuth2Client } from "google-auth-library"
|
import { OAuth2Client } from "google-auth-library"
|
||||||
import { DatasourcePlus } from "./base/datasourcePlus"
|
import { DatasourcePlus } from "./base/datasourcePlus"
|
||||||
import { Row, Table, TableSchema } from "../definitions/common"
|
import { Table, TableSchema } from "../definitions/common"
|
||||||
import { buildExternalTableId } from "./utils"
|
import { buildExternalTableId } from "./utils"
|
||||||
import { DataSourceOperation, FieldTypes } from "../constants"
|
import { DataSourceOperation, FieldTypes } from "../constants"
|
||||||
import { GoogleSpreadsheet } from "google-spreadsheet"
|
import { GoogleSpreadsheet } from "google-spreadsheet"
|
||||||
import { table } from "console"
|
|
||||||
|
|
||||||
module GoogleSheetsModule {
|
module GoogleSheetsModule {
|
||||||
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
||||||
|
@ -112,6 +111,10 @@ module GoogleSheetsModule {
|
||||||
this.client = new GoogleSpreadsheet(spreadsheetId)
|
this.client = new GoogleSpreadsheet(spreadsheetId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getBindingIdentifier() {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pull the spreadsheet ID out from a valid google sheets URL
|
* Pull the spreadsheet ID out from a valid google sheets URL
|
||||||
* @param spreadsheetId - the URL or standard spreadsheetId of the google sheet
|
* @param spreadsheetId - the URL or standard spreadsheetId of the google sheet
|
||||||
|
|
|
@ -79,34 +79,9 @@ module MSSQLModule {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
async function internalQuery(
|
|
||||||
client: any,
|
|
||||||
query: SqlQuery,
|
|
||||||
operation: string | undefined = undefined
|
|
||||||
) {
|
|
||||||
const request = client.request()
|
|
||||||
try {
|
|
||||||
if (Array.isArray(query.bindings)) {
|
|
||||||
let count = 0
|
|
||||||
for (let binding of query.bindings) {
|
|
||||||
request.input(`p${count++}`, binding)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// this is a hack to get the inserted ID back,
|
|
||||||
// no way to do this with Knex nicely
|
|
||||||
const sql =
|
|
||||||
operation === Operation.CREATE
|
|
||||||
? `${query.sql}; SELECT SCOPE_IDENTITY() AS id;`
|
|
||||||
: query.sql
|
|
||||||
return await request.query(sql)
|
|
||||||
} catch (err) {
|
|
||||||
// @ts-ignore
|
|
||||||
throw new Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SqlServerIntegration extends Sql implements DatasourcePlus {
|
class SqlServerIntegration extends Sql implements DatasourcePlus {
|
||||||
private readonly config: MSSQLConfig
|
private readonly config: MSSQLConfig
|
||||||
|
private index: number = 0
|
||||||
static pool: any
|
static pool: any
|
||||||
public tables: Record<string, Table> = {}
|
public tables: Record<string, Table> = {}
|
||||||
public schemaErrors: Record<string, string> = {}
|
public schemaErrors: Record<string, string> = {}
|
||||||
|
@ -121,6 +96,33 @@ module MSSQLModule {
|
||||||
TABLES_SQL =
|
TABLES_SQL =
|
||||||
"SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'"
|
"SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'"
|
||||||
|
|
||||||
|
async internalQuery(
|
||||||
|
query: SqlQuery,
|
||||||
|
operation: string | undefined = undefined
|
||||||
|
) {
|
||||||
|
const client = this.client
|
||||||
|
const request = client.request()
|
||||||
|
this.index = 0
|
||||||
|
try {
|
||||||
|
if (Array.isArray(query.bindings)) {
|
||||||
|
let count = 0
|
||||||
|
for (let binding of query.bindings) {
|
||||||
|
request.input(`p${count++}`, binding)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// this is a hack to get the inserted ID back,
|
||||||
|
// no way to do this with Knex nicely
|
||||||
|
const sql =
|
||||||
|
operation === Operation.CREATE
|
||||||
|
? `${query.sql}; SELECT SCOPE_IDENTITY() AS id;`
|
||||||
|
: query.sql
|
||||||
|
return await request.query(sql)
|
||||||
|
} catch (err) {
|
||||||
|
// @ts-ignore
|
||||||
|
throw new Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getDefinitionSQL(tableName: string) {
|
getDefinitionSQL(tableName: string) {
|
||||||
return `select *
|
return `select *
|
||||||
from INFORMATION_SCHEMA.COLUMNS
|
from INFORMATION_SCHEMA.COLUMNS
|
||||||
|
@ -165,6 +167,10 @@ module MSSQLModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getBindingIdentifier(): string {
|
||||||
|
return `(@p${this.index++})`
|
||||||
|
}
|
||||||
|
|
||||||
async connect() {
|
async connect() {
|
||||||
try {
|
try {
|
||||||
this.client = await this.pool.connect()
|
this.client = await this.pool.connect()
|
||||||
|
@ -175,7 +181,7 @@ module MSSQLModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
async runSQL(sql: string) {
|
async runSQL(sql: string) {
|
||||||
return (await internalQuery(this.client, getSqlQuery(sql))).recordset
|
return (await this.internalQuery(getSqlQuery(sql))).recordset
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -238,33 +244,32 @@ module MSSQLModule {
|
||||||
|
|
||||||
async read(query: SqlQuery | string) {
|
async read(query: SqlQuery | string) {
|
||||||
await this.connect()
|
await this.connect()
|
||||||
const response = await internalQuery(this.client, getSqlQuery(query))
|
const response = await this.internalQuery(getSqlQuery(query))
|
||||||
return response.recordset
|
return response.recordset
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(query: SqlQuery | string) {
|
async create(query: SqlQuery | string) {
|
||||||
await this.connect()
|
await this.connect()
|
||||||
const response = await internalQuery(this.client, getSqlQuery(query))
|
const response = await this.internalQuery(getSqlQuery(query))
|
||||||
return response.recordset || [{ created: true }]
|
return response.recordset || [{ created: true }]
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(query: SqlQuery | string) {
|
async update(query: SqlQuery | string) {
|
||||||
await this.connect()
|
await this.connect()
|
||||||
const response = await internalQuery(this.client, getSqlQuery(query))
|
const response = await this.internalQuery(getSqlQuery(query))
|
||||||
return response.recordset || [{ updated: true }]
|
return response.recordset || [{ updated: true }]
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(query: SqlQuery | string) {
|
async delete(query: SqlQuery | string) {
|
||||||
await this.connect()
|
await this.connect()
|
||||||
const response = await internalQuery(this.client, getSqlQuery(query))
|
const response = await this.internalQuery(getSqlQuery(query))
|
||||||
return response.recordset || [{ deleted: true }]
|
return response.recordset || [{ deleted: true }]
|
||||||
}
|
}
|
||||||
|
|
||||||
async query(json: QueryJson) {
|
async query(json: QueryJson) {
|
||||||
await this.connect()
|
await this.connect()
|
||||||
const operation = this._operation(json)
|
const operation = this._operation(json)
|
||||||
const queryFn = (query: any, op: string) =>
|
const queryFn = (query: any, op: string) => this.internalQuery(query, op)
|
||||||
internalQuery(this.client, query, op)
|
|
||||||
const processFn = (result: any) =>
|
const processFn = (result: any) =>
|
||||||
result.recordset ? result.recordset : [{ [operation]: true }]
|
result.recordset ? result.recordset : [{ [operation]: true }]
|
||||||
return this.queryWithReturning(json, queryFn, processFn)
|
return this.queryWithReturning(json, queryFn, processFn)
|
||||||
|
|
|
@ -80,33 +80,6 @@ module MySQLModule {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
function internalQuery(
|
|
||||||
client: any,
|
|
||||||
query: SqlQuery,
|
|
||||||
connect: boolean = true
|
|
||||||
): Promise<any[] | any> {
|
|
||||||
// Node MySQL is callback based, so we must wrap our call in a promise
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (connect) {
|
|
||||||
client.connect()
|
|
||||||
}
|
|
||||||
return client.query(
|
|
||||||
query.sql,
|
|
||||||
query.bindings || {},
|
|
||||||
(error: any, results: object[]) => {
|
|
||||||
if (error) {
|
|
||||||
reject(error)
|
|
||||||
} else {
|
|
||||||
resolve(results)
|
|
||||||
}
|
|
||||||
if (connect) {
|
|
||||||
client.end()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
class MySQLIntegration extends Sql implements DatasourcePlus {
|
class MySQLIntegration extends Sql implements DatasourcePlus {
|
||||||
private config: MySQLConfig
|
private config: MySQLConfig
|
||||||
private readonly client: any
|
private readonly client: any
|
||||||
|
@ -122,14 +95,44 @@ module MySQLModule {
|
||||||
this.client = mysql.createConnection(config)
|
this.client = mysql.createConnection(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getBindingIdentifier(): string {
|
||||||
|
return "?"
|
||||||
|
}
|
||||||
|
|
||||||
|
internalQuery(
|
||||||
|
query: SqlQuery,
|
||||||
|
connect: boolean = true
|
||||||
|
): Promise<any[] | any> {
|
||||||
|
const client = this.client
|
||||||
|
// Node MySQL is callback based, so we must wrap our call in a promise
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (connect) {
|
||||||
|
client.connect()
|
||||||
|
}
|
||||||
|
return client.query(
|
||||||
|
query.sql,
|
||||||
|
query.bindings || {},
|
||||||
|
(error: any, results: object[]) => {
|
||||||
|
if (error) {
|
||||||
|
reject(error)
|
||||||
|
} else {
|
||||||
|
resolve(results)
|
||||||
|
}
|
||||||
|
if (connect) {
|
||||||
|
client.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async buildSchema(datasourceId: string, entities: Record<string, Table>) {
|
async buildSchema(datasourceId: string, entities: Record<string, Table>) {
|
||||||
const tables: { [key: string]: Table } = {}
|
const tables: { [key: string]: Table } = {}
|
||||||
const database = this.config.database
|
const database = this.config.database
|
||||||
this.client.connect()
|
this.client.connect()
|
||||||
|
|
||||||
// get the tables first
|
// get the tables first
|
||||||
const tablesResp = await internalQuery(
|
const tablesResp = await this.internalQuery(
|
||||||
this.client,
|
|
||||||
{ sql: "SHOW TABLES;" },
|
{ sql: "SHOW TABLES;" },
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
@ -141,8 +144,7 @@ module MySQLModule {
|
||||||
for (let tableName of tableNames) {
|
for (let tableName of tableNames) {
|
||||||
const primaryKeys = []
|
const primaryKeys = []
|
||||||
const schema: TableSchema = {}
|
const schema: TableSchema = {}
|
||||||
const descResp = await internalQuery(
|
const descResp = await this.internalQuery(
|
||||||
this.client,
|
|
||||||
{ sql: `DESCRIBE \`${tableName}\`;` },
|
{ sql: `DESCRIBE \`${tableName}\`;` },
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
@ -182,27 +184,27 @@ module MySQLModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(query: SqlQuery | string) {
|
async create(query: SqlQuery | string) {
|
||||||
const results = await internalQuery(this.client, getSqlQuery(query))
|
const results = await this.internalQuery(getSqlQuery(query))
|
||||||
return results.length ? results : [{ created: true }]
|
return results.length ? results : [{ created: true }]
|
||||||
}
|
}
|
||||||
|
|
||||||
async read(query: SqlQuery | string) {
|
async read(query: SqlQuery | string) {
|
||||||
return internalQuery(this.client, getSqlQuery(query))
|
return this.internalQuery(getSqlQuery(query))
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(query: SqlQuery | string) {
|
async update(query: SqlQuery | string) {
|
||||||
const results = await internalQuery(this.client, getSqlQuery(query))
|
const results = await this.internalQuery(getSqlQuery(query))
|
||||||
return results.length ? results : [{ updated: true }]
|
return results.length ? results : [{ updated: true }]
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(query: SqlQuery | string) {
|
async delete(query: SqlQuery | string) {
|
||||||
const results = await internalQuery(this.client, getSqlQuery(query))
|
const results = await this.internalQuery(getSqlQuery(query))
|
||||||
return results.length ? results : [{ deleted: true }]
|
return results.length ? results : [{ deleted: true }]
|
||||||
}
|
}
|
||||||
|
|
||||||
async query(json: QueryJson) {
|
async query(json: QueryJson) {
|
||||||
this.client.connect()
|
this.client.connect()
|
||||||
const queryFn = (query: any) => internalQuery(this.client, query, false)
|
const queryFn = (query: any) => this.internalQuery(query, false)
|
||||||
const output = await this.queryWithReturning(json, queryFn)
|
const output = await this.queryWithReturning(json, queryFn)
|
||||||
this.client.end()
|
this.client.end()
|
||||||
return output
|
return output
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
import {
|
import {
|
||||||
Integration,
|
|
||||||
DatasourceFieldTypes,
|
DatasourceFieldTypes,
|
||||||
|
Integration,
|
||||||
|
Operation,
|
||||||
|
QueryJson,
|
||||||
QueryTypes,
|
QueryTypes,
|
||||||
SqlQuery,
|
SqlQuery,
|
||||||
QueryJson,
|
|
||||||
Operation,
|
|
||||||
} from "../definitions/datasource"
|
} from "../definitions/datasource"
|
||||||
import {
|
import {
|
||||||
finaliseExternalTables,
|
|
||||||
getSqlQuery,
|
|
||||||
buildExternalTableId,
|
buildExternalTableId,
|
||||||
convertSqlType,
|
convertSqlType,
|
||||||
|
finaliseExternalTables,
|
||||||
|
getSqlQuery,
|
||||||
SqlClients,
|
SqlClients,
|
||||||
} from "./utils"
|
} from "./utils"
|
||||||
import oracledb, {
|
import oracledb, {
|
||||||
ExecuteOptions,
|
BindParameters,
|
||||||
Result,
|
|
||||||
Connection,
|
Connection,
|
||||||
ConnectionAttributes,
|
ConnectionAttributes,
|
||||||
BindParameters,
|
ExecuteOptions,
|
||||||
|
Result,
|
||||||
} from "oracledb"
|
} from "oracledb"
|
||||||
import Sql from "./base/sql"
|
import Sql from "./base/sql"
|
||||||
import { Table } from "../definitions/common"
|
import { Table } from "../definitions/common"
|
||||||
|
@ -137,6 +137,7 @@ module OracleModule {
|
||||||
|
|
||||||
class OracleIntegration extends Sql implements DatasourcePlus {
|
class OracleIntegration extends Sql implements DatasourcePlus {
|
||||||
private readonly config: OracleConfig
|
private readonly config: OracleConfig
|
||||||
|
private index: number = 1
|
||||||
|
|
||||||
public tables: Record<string, Table> = {}
|
public tables: Record<string, Table> = {}
|
||||||
public schemaErrors: Record<string, string> = {}
|
public schemaErrors: Record<string, string> = {}
|
||||||
|
@ -174,6 +175,10 @@ module OracleModule {
|
||||||
this.config = config
|
this.config = config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getBindingIdentifier(): string {
|
||||||
|
return `:${this.index++}`
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map the flat tabular columns and constraints data into a nested object
|
* Map the flat tabular columns and constraints data into a nested object
|
||||||
*/
|
*/
|
||||||
|
@ -233,20 +238,14 @@ module OracleModule {
|
||||||
return oracleTables
|
return oracleTables
|
||||||
}
|
}
|
||||||
|
|
||||||
private isSupportedColumn(column: OracleColumn) {
|
private static isSupportedColumn(column: OracleColumn) {
|
||||||
if (UNSUPPORTED_TYPES.includes(column.type)) {
|
return !UNSUPPORTED_TYPES.includes(column.type)
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private isAutoColumn(column: OracleColumn) {
|
private static isAutoColumn(column: OracleColumn) {
|
||||||
if (column.default && column.default.toLowerCase().includes("nextval")) {
|
return !!(
|
||||||
return true
|
column.default && column.default.toLowerCase().includes("nextval")
|
||||||
}
|
)
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -254,7 +253,7 @@ module OracleModule {
|
||||||
* This matches the default behaviour for generating DDL used in knex.
|
* This matches the default behaviour for generating DDL used in knex.
|
||||||
*/
|
*/
|
||||||
private isBooleanType(column: OracleColumn): boolean {
|
private isBooleanType(column: OracleColumn): boolean {
|
||||||
if (
|
return (
|
||||||
column.type.toLowerCase() === "number" &&
|
column.type.toLowerCase() === "number" &&
|
||||||
Object.values(column.constraints).filter(c => {
|
Object.values(column.constraints).filter(c => {
|
||||||
if (
|
if (
|
||||||
|
@ -273,11 +272,7 @@ module OracleModule {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}).length > 0
|
}).length > 0
|
||||||
) {
|
)
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private internalConvertType(column: OracleColumn): string {
|
private internalConvertType(column: OracleColumn): string {
|
||||||
|
@ -317,7 +312,9 @@ module OracleModule {
|
||||||
// iterate each column on the table
|
// iterate each column on the table
|
||||||
Object.values(oracleTable.columns)
|
Object.values(oracleTable.columns)
|
||||||
// remove columns that we can't read / save
|
// remove columns that we can't read / save
|
||||||
.filter(oracleColumn => this.isSupportedColumn(oracleColumn))
|
.filter(oracleColumn =>
|
||||||
|
OracleIntegration.isSupportedColumn(oracleColumn)
|
||||||
|
)
|
||||||
// match the order of the columns in the db
|
// match the order of the columns in the db
|
||||||
.sort((c1, c2) => c1.id - c2.id)
|
.sort((c1, c2) => c1.id - c2.id)
|
||||||
.forEach(oracleColumn => {
|
.forEach(oracleColumn => {
|
||||||
|
@ -325,7 +322,7 @@ module OracleModule {
|
||||||
let fieldSchema = table.schema[columnName]
|
let fieldSchema = table.schema[columnName]
|
||||||
if (!fieldSchema) {
|
if (!fieldSchema) {
|
||||||
fieldSchema = {
|
fieldSchema = {
|
||||||
autocolumn: this.isAutoColumn(oracleColumn),
|
autocolumn: OracleIntegration.isAutoColumn(oracleColumn),
|
||||||
name: columnName,
|
name: columnName,
|
||||||
type: this.internalConvertType(oracleColumn),
|
type: this.internalConvertType(oracleColumn),
|
||||||
}
|
}
|
||||||
|
@ -351,18 +348,13 @@ module OracleModule {
|
||||||
private async internalQuery<T>(query: SqlQuery): Promise<Result<T>> {
|
private async internalQuery<T>(query: SqlQuery): Promise<Result<T>> {
|
||||||
let connection
|
let connection
|
||||||
try {
|
try {
|
||||||
|
this.index = 1
|
||||||
connection = await this.getConnection()
|
connection = await this.getConnection()
|
||||||
|
|
||||||
const options: ExecuteOptions = { autoCommit: true }
|
const options: ExecuteOptions = { autoCommit: true }
|
||||||
const bindings: BindParameters = query.bindings || []
|
const bindings: BindParameters = query.bindings || []
|
||||||
|
|
||||||
const result: Result<T> = await connection.execute<T>(
|
return await connection.execute<T>(query.sql, bindings, options)
|
||||||
query.sql,
|
|
||||||
bindings,
|
|
||||||
options
|
|
||||||
)
|
|
||||||
|
|
||||||
return result
|
|
||||||
} finally {
|
} finally {
|
||||||
if (connection) {
|
if (connection) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -103,30 +103,11 @@ module PostgresModule {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
async function internalQuery(client: any, query: SqlQuery) {
|
|
||||||
// need to handle a specific issue with json data types in postgres,
|
|
||||||
// new lines inside the JSON data will break it
|
|
||||||
if (query && query.sql) {
|
|
||||||
const matches = query.sql.match(JSON_REGEX)
|
|
||||||
if (matches && matches.length > 0) {
|
|
||||||
for (let match of matches) {
|
|
||||||
const escaped = escapeDangerousCharacters(match)
|
|
||||||
query.sql = query.sql.replace(match, escaped)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return await client.query(query.sql, query.bindings || [])
|
|
||||||
} catch (err) {
|
|
||||||
// @ts-ignore
|
|
||||||
throw new Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PostgresIntegration extends Sql implements DatasourcePlus {
|
class PostgresIntegration extends Sql implements DatasourcePlus {
|
||||||
static pool: any
|
static pool: any
|
||||||
private readonly client: any
|
private readonly client: any
|
||||||
private readonly config: PostgresConfig
|
private readonly config: PostgresConfig
|
||||||
|
private index: number = 1
|
||||||
public tables: Record<string, Table> = {}
|
public tables: Record<string, Table> = {}
|
||||||
public schemaErrors: Record<string, string> = {}
|
public schemaErrors: Record<string, string> = {}
|
||||||
|
|
||||||
|
@ -163,6 +144,32 @@ module PostgresModule {
|
||||||
this.setSchema()
|
this.setSchema()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getBindingIdentifier(): string {
|
||||||
|
return `$${this.index++}`
|
||||||
|
}
|
||||||
|
|
||||||
|
async internalQuery(query: SqlQuery) {
|
||||||
|
const client = this.client
|
||||||
|
this.index = 1
|
||||||
|
// need to handle a specific issue with json data types in postgres,
|
||||||
|
// new lines inside the JSON data will break it
|
||||||
|
if (query && query.sql) {
|
||||||
|
const matches = query.sql.match(JSON_REGEX)
|
||||||
|
if (matches && matches.length > 0) {
|
||||||
|
for (let match of matches) {
|
||||||
|
const escaped = escapeDangerousCharacters(match)
|
||||||
|
query.sql = query.sql.replace(match, escaped)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return await client.query(query.sql, query.bindings || [])
|
||||||
|
} catch (err) {
|
||||||
|
// @ts-ignore
|
||||||
|
throw new Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setSchema() {
|
setSchema() {
|
||||||
if (!this.config.schema) {
|
if (!this.config.schema) {
|
||||||
this.config.schema = "public"
|
this.config.schema = "public"
|
||||||
|
@ -241,22 +248,22 @@ module PostgresModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(query: SqlQuery | string) {
|
async create(query: SqlQuery | string) {
|
||||||
const response = await internalQuery(this.client, getSqlQuery(query))
|
const response = await this.internalQuery(getSqlQuery(query))
|
||||||
return response.rows.length ? response.rows : [{ created: true }]
|
return response.rows.length ? response.rows : [{ created: true }]
|
||||||
}
|
}
|
||||||
|
|
||||||
async read(query: SqlQuery | string) {
|
async read(query: SqlQuery | string) {
|
||||||
const response = await internalQuery(this.client, getSqlQuery(query))
|
const response = await this.internalQuery(getSqlQuery(query))
|
||||||
return response.rows
|
return response.rows
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(query: SqlQuery | string) {
|
async update(query: SqlQuery | string) {
|
||||||
const response = await internalQuery(this.client, getSqlQuery(query))
|
const response = await this.internalQuery(getSqlQuery(query))
|
||||||
return response.rows.length ? response.rows : [{ updated: true }]
|
return response.rows.length ? response.rows : [{ updated: true }]
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(query: SqlQuery | string) {
|
async delete(query: SqlQuery | string) {
|
||||||
const response = await internalQuery(this.client, getSqlQuery(query))
|
const response = await this.internalQuery(getSqlQuery(query))
|
||||||
return response.rows.length ? response.rows : [{ deleted: true }]
|
return response.rows.length ? response.rows : [{ deleted: true }]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,11 +273,11 @@ module PostgresModule {
|
||||||
if (Array.isArray(input)) {
|
if (Array.isArray(input)) {
|
||||||
const responses = []
|
const responses = []
|
||||||
for (let query of input) {
|
for (let query of input) {
|
||||||
responses.push(await internalQuery(this.client, query))
|
responses.push(await this.internalQuery(query))
|
||||||
}
|
}
|
||||||
return responses
|
return responses
|
||||||
} else {
|
} else {
|
||||||
const response = await internalQuery(this.client, input)
|
const response = await this.internalQuery(input)
|
||||||
return response.rows.length ? response.rows : [{ [operation]: true }]
|
return response.rows.length ? response.rows : [{ [operation]: true }]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,12 @@ const threadUtils = require("./utils")
|
||||||
threadUtils.threadSetup()
|
threadUtils.threadSetup()
|
||||||
const ScriptRunner = require("../utilities/scriptRunner")
|
const ScriptRunner = require("../utilities/scriptRunner")
|
||||||
const { integrations } = require("../integrations")
|
const { integrations } = require("../integrations")
|
||||||
const { processStringSync } = require("@budibase/string-templates")
|
const {
|
||||||
|
processStringSync,
|
||||||
|
findHBSBlocks,
|
||||||
|
} = require("@budibase/string-templates")
|
||||||
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
|
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
|
||||||
|
const { isSQL } = require("../integrations/utils")
|
||||||
|
|
||||||
class QueryRunner {
|
class QueryRunner {
|
||||||
constructor(input, flags = { noRecursiveQuery: false }) {
|
constructor(input, flags = { noRecursiveQuery: false }) {
|
||||||
|
@ -23,23 +27,47 @@ class QueryRunner {
|
||||||
this.hasRerun = false
|
this.hasRerun = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interpolateSQL(fields, parameters, integration) {
|
||||||
|
let sql = fields.sql
|
||||||
|
if (!sql) {
|
||||||
|
return fields
|
||||||
|
}
|
||||||
|
const bindings = findHBSBlocks(sql)
|
||||||
|
let variables = []
|
||||||
|
for (let binding of bindings) {
|
||||||
|
let variable = integration.getBindingIdentifier()
|
||||||
|
variables.push(binding)
|
||||||
|
sql = sql.replace(binding, variable)
|
||||||
|
}
|
||||||
|
// replicate the knex structure
|
||||||
|
fields.sql = sql
|
||||||
|
fields.bindings = this.enrichQueryFields(variables, parameters)
|
||||||
|
return fields
|
||||||
|
}
|
||||||
|
|
||||||
async execute() {
|
async execute() {
|
||||||
let { datasource, fields, queryVerb, transformer } = this
|
let { datasource, fields, queryVerb, transformer } = this
|
||||||
// pre-query, make sure datasource variables are added to parameters
|
|
||||||
const parameters = await this.addDatasourceVariables()
|
|
||||||
let query = this.enrichQueryFields(fields, parameters)
|
|
||||||
|
|
||||||
// Add pagination values for REST queries
|
|
||||||
if (this.pagination) {
|
|
||||||
query.paginationValues = this.pagination
|
|
||||||
}
|
|
||||||
|
|
||||||
const Integration = integrations[datasource.source]
|
const Integration = integrations[datasource.source]
|
||||||
if (!Integration) {
|
if (!Integration) {
|
||||||
throw "Integration type does not exist."
|
throw "Integration type does not exist."
|
||||||
}
|
}
|
||||||
const integration = new Integration(datasource.config)
|
const integration = new Integration(datasource.config)
|
||||||
|
|
||||||
|
// pre-query, make sure datasource variables are added to parameters
|
||||||
|
const parameters = await this.addDatasourceVariables()
|
||||||
|
let query
|
||||||
|
// handle SQL injections by interpolating the variables
|
||||||
|
if (isSQL(datasource)) {
|
||||||
|
query = this.interpolateSQL(fields, parameters, integration)
|
||||||
|
} else {
|
||||||
|
query = this.enrichQueryFields(fields, parameters)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add pagination values for REST queries
|
||||||
|
if (this.pagination) {
|
||||||
|
query.paginationValues = this.pagination
|
||||||
|
}
|
||||||
|
|
||||||
let output = threadUtils.formatResponse(await integration[queryVerb](query))
|
let output = threadUtils.formatResponse(await integration[queryVerb](query))
|
||||||
let rows = output,
|
let rows = output,
|
||||||
info = undefined,
|
info = undefined,
|
||||||
|
@ -179,7 +207,7 @@ class QueryRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
enrichQueryFields(fields, parameters = {}) {
|
enrichQueryFields(fields, parameters = {}) {
|
||||||
const enrichedQuery = {}
|
const enrichedQuery = Array.isArray(fields) ? [] : {}
|
||||||
|
|
||||||
// enrich the fields with dynamic parameters
|
// enrich the fields with dynamic parameters
|
||||||
for (let key of Object.keys(fields)) {
|
for (let key of Object.keys(fields)) {
|
||||||
|
|
|
@ -995,10 +995,10 @@
|
||||||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||||
|
|
||||||
"@budibase/backend-core@^1.0.79-alpha.7":
|
"@budibase/backend-core@^1.0.79-alpha.9":
|
||||||
version "1.0.79-alpha.7"
|
version "1.0.79-alpha.9"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.0.79-alpha.7.tgz#57e8319118b425cc228173d1ec8bf19843e1a417"
|
resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.0.79-alpha.9.tgz#5d770d65f0375d93a382d8a32d0427e935fb2152"
|
||||||
integrity sha512-Ao4dR6zwnJa4mYiRyl5lULYm+wsYwOi3sxDIjt5vmurqUL2JTuVUrGt1MAq1N6K11xQpbQQJAFvgfxBgn9aEMg==
|
integrity sha512-EV9hreLMvapZqZ/P99u4Ke2hO1w1GamGBHFri5MzLA9Njc5YRJzoDoy/Awg7k1piu3OIW2Sjk0b5VA+v3iaMnA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@techpass/passport-openidconnect" "^0.3.0"
|
"@techpass/passport-openidconnect" "^0.3.0"
|
||||||
aws-sdk "^2.901.0"
|
aws-sdk "^2.901.0"
|
||||||
|
@ -1068,7 +1068,7 @@
|
||||||
svelte-flatpickr "^3.2.3"
|
svelte-flatpickr "^3.2.3"
|
||||||
svelte-portal "^1.0.0"
|
svelte-portal "^1.0.0"
|
||||||
|
|
||||||
"@budibase/bbui@^1.0.79-alpha.7":
|
"@budibase/bbui@^1.0.79-alpha.9":
|
||||||
version "1.58.13"
|
version "1.58.13"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.58.13.tgz#59df9c73def2d81c75dcbd2266c52c19db88dbd7"
|
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.58.13.tgz#59df9c73def2d81c75dcbd2266c52c19db88dbd7"
|
||||||
integrity sha512-Zk6CKXdBfKsTVzA1Xs5++shdSSZLfphVpZuKVbjfzkgtuhyH7ruucexuSHEpFsxjW5rEKgKIBoRFzCK5vPvN0w==
|
integrity sha512-Zk6CKXdBfKsTVzA1Xs5++shdSSZLfphVpZuKVbjfzkgtuhyH7ruucexuSHEpFsxjW5rEKgKIBoRFzCK5vPvN0w==
|
||||||
|
@ -1080,14 +1080,14 @@
|
||||||
svelte-portal "^1.0.0"
|
svelte-portal "^1.0.0"
|
||||||
turndown "^7.0.0"
|
turndown "^7.0.0"
|
||||||
|
|
||||||
"@budibase/client@^1.0.79-alpha.7":
|
"@budibase/client@^1.0.79-alpha.9":
|
||||||
version "1.0.79-alpha.7"
|
version "1.0.79-alpha.9"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/client/-/client-1.0.79-alpha.7.tgz#d225ac5bd68fa9ecb81114791e6d931246da9637"
|
resolved "https://registry.yarnpkg.com/@budibase/client/-/client-1.0.79-alpha.9.tgz#526efb411c85cc871b0aa2717a6d1dce1c6496ef"
|
||||||
integrity sha512-7faCcIlXyOf660PwpOMCt9/X2liiTuCsPGUpLsJQu2j9CcVZ5vV+au0CX7dtqewtPNuIL0mF3G7ZOpBTvXx4NQ==
|
integrity sha512-x9F7s02jcgU1QlpUaEDj1kvMJqRJPzw+wcZfFyVPkRjZtZo9PnzDXQ+kZ6bqiKfyf/qNJ1SM1jzEAl1uzUj7vA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@budibase/bbui" "^1.0.79-alpha.7"
|
"@budibase/bbui" "^1.0.79-alpha.9"
|
||||||
"@budibase/frontend-core" "^1.0.79-alpha.7"
|
"@budibase/frontend-core" "^1.0.79-alpha.9"
|
||||||
"@budibase/string-templates" "^1.0.79-alpha.7"
|
"@budibase/string-templates" "^1.0.79-alpha.9"
|
||||||
"@spectrum-css/button" "^3.0.3"
|
"@spectrum-css/button" "^3.0.3"
|
||||||
"@spectrum-css/card" "^3.0.3"
|
"@spectrum-css/card" "^3.0.3"
|
||||||
"@spectrum-css/divider" "^1.0.3"
|
"@spectrum-css/divider" "^1.0.3"
|
||||||
|
@ -1106,12 +1106,12 @@
|
||||||
svelte-flatpickr "^3.1.0"
|
svelte-flatpickr "^3.1.0"
|
||||||
svelte-spa-router "^3.0.5"
|
svelte-spa-router "^3.0.5"
|
||||||
|
|
||||||
"@budibase/frontend-core@^1.0.79-alpha.7":
|
"@budibase/frontend-core@^1.0.79-alpha.9":
|
||||||
version "1.0.79-alpha.7"
|
version "1.0.79-alpha.9"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/frontend-core/-/frontend-core-1.0.79-alpha.7.tgz#cba8f61932f966dc3f19cc7d5fed45d832ee676e"
|
resolved "https://registry.yarnpkg.com/@budibase/frontend-core/-/frontend-core-1.0.79-alpha.9.tgz#3441f03370744204d3614a106e8544ceb70b2abd"
|
||||||
integrity sha512-mEspQXLUnjvNcL7QfDN1qIFGRo+AfdcaEq23gKAWXF1R+Byy7VCYDzcowzJY/TT6B4BSq3z6s57z3ILKtqI7zA==
|
integrity sha512-bZrV2ifcGGK/G1adAGqRHJ9OGGnGMzany9bonzInrF1YoqfT9TE9sGpfDdm7I8jfvSsidXUEY0/KJBLPMo4+4g==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@budibase/bbui" "^1.0.79-alpha.7"
|
"@budibase/bbui" "^1.0.79-alpha.9"
|
||||||
lodash "^4.17.21"
|
lodash "^4.17.21"
|
||||||
svelte "^3.46.2"
|
svelte "^3.46.2"
|
||||||
|
|
||||||
|
@ -1158,10 +1158,10 @@
|
||||||
svelte-apexcharts "^1.0.2"
|
svelte-apexcharts "^1.0.2"
|
||||||
svelte-flatpickr "^3.1.0"
|
svelte-flatpickr "^3.1.0"
|
||||||
|
|
||||||
"@budibase/string-templates@^1.0.79-alpha.7":
|
"@budibase/string-templates@^1.0.79-alpha.9":
|
||||||
version "1.0.79-alpha.7"
|
version "1.0.79-alpha.9"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-1.0.79-alpha.7.tgz#3e5235e05f13fe406cae62862110f841788d1bc0"
|
resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-1.0.79-alpha.9.tgz#5b1b9401f97ca691b4a74c10901bb878a14067b6"
|
||||||
integrity sha512-wdnk0wi9vuSYY7vimIGV1+i0dSONOBg5deZia8v9O8XM9OmJohLUIkJdMNhhv9OCxyeC53gauaxhVdKeop6kmA==
|
integrity sha512-BlqiCLIobVDoXV4UBeyZ5UaTF8INihvmR+ihr0862TOhdcthSRkb2HOfoB3aAm5XYhe7NpLnJepDRG+1sefDgA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@budibase/handlebars-helpers" "^0.11.8"
|
"@budibase/handlebars-helpers" "^0.11.8"
|
||||||
dayjs "^1.10.4"
|
dayjs "^1.10.4"
|
||||||
|
@ -2386,6 +2386,11 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/types" "^7.3.0"
|
"@babel/types" "^7.3.0"
|
||||||
|
|
||||||
|
"@types/bluebird@*":
|
||||||
|
version "3.5.36"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.36.tgz#00d9301d4dc35c2f6465a8aec634bb533674c652"
|
||||||
|
integrity sha512-HBNx4lhkxN7bx6P0++W8E289foSu8kO8GCk2unhuVggO+cE7rh9DhZUyPhUxNRG9m+5B5BTKxZQ5ZP92x/mx9Q==
|
||||||
|
|
||||||
"@types/body-parser@*":
|
"@types/body-parser@*":
|
||||||
version "1.19.2"
|
version "1.19.2"
|
||||||
resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0"
|
resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0"
|
||||||
|
@ -2418,6 +2423,13 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/content-disposition/-/content-disposition-0.5.4.tgz#de48cf01c79c9f1560bcfd8ae43217ab028657f8"
|
resolved "https://registry.yarnpkg.com/@types/content-disposition/-/content-disposition-0.5.4.tgz#de48cf01c79c9f1560bcfd8ae43217ab028657f8"
|
||||||
integrity sha512-0mPF08jn9zYI0n0Q/Pnz7C4kThdSt+6LD4amsrYDDpgBfrVWa3TcCOxKX1zkGgYniGagRv8heN2cbh+CAn+uuQ==
|
integrity sha512-0mPF08jn9zYI0n0Q/Pnz7C4kThdSt+6LD4amsrYDDpgBfrVWa3TcCOxKX1zkGgYniGagRv8heN2cbh+CAn+uuQ==
|
||||||
|
|
||||||
|
"@types/continuation-local-storage@*":
|
||||||
|
version "3.2.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/continuation-local-storage/-/continuation-local-storage-3.2.4.tgz#655c8ffd9327aa60fb8ae773a5f2efbc973a7cbb"
|
||||||
|
integrity sha512-OT32vCVMymU1JMPKDeY0lX3cduAr0Pm/VwIbxygMeDS4lRcv57qYXn9bMwBRcRnEpXKBb/r4xYaZCARTZllP0A==
|
||||||
|
dependencies:
|
||||||
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/cookiejar@*":
|
"@types/cookiejar@*":
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.2.tgz#66ad9331f63fe8a3d3d9d8c6e3906dd10f6446e8"
|
resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.2.tgz#66ad9331f63fe8a3d3d9d8c6e3906dd10f6446e8"
|
||||||
|
@ -2573,6 +2585,16 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/koa" "*"
|
"@types/koa" "*"
|
||||||
|
|
||||||
|
"@types/koa2-ratelimit@^0.9.2":
|
||||||
|
version "0.9.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/koa2-ratelimit/-/koa2-ratelimit-0.9.2.tgz#5853e2db9d61ea596ffa8c0ef5ec545c5f5351f0"
|
||||||
|
integrity sha512-wHBO8fCFUX86lc41GNj/WR1Ao6CW47bPWJO3b14LLSc8j927ev8F/ELj7FKXlyUPWC/CFKZTW8PpKLufjK8Eqg==
|
||||||
|
dependencies:
|
||||||
|
"@types/koa" "*"
|
||||||
|
"@types/mongoose" "5.10.5"
|
||||||
|
"@types/redis" "^2.8.0"
|
||||||
|
"@types/sequelize" "*"
|
||||||
|
|
||||||
"@types/koa@*", "@types/koa@^2.13.3":
|
"@types/koa@*", "@types/koa@^2.13.3":
|
||||||
version "2.13.4"
|
version "2.13.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.13.4.tgz#10620b3f24a8027ef5cbae88b393d1b31205726b"
|
resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.13.4.tgz#10620b3f24a8027ef5cbae88b393d1b31205726b"
|
||||||
|
@ -2587,11 +2609,31 @@
|
||||||
"@types/koa-compose" "*"
|
"@types/koa-compose" "*"
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/lodash@*":
|
||||||
|
version "4.14.179"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.179.tgz#490ec3288088c91295780237d2497a3aa9dfb5c5"
|
||||||
|
integrity sha512-uwc1x90yCKqGcIOAT6DwOSuxnrAbpkdPsUOZtwrXb4D/6wZs+6qG7QnIawDuZWg0sWpxl+ltIKCaLoMlna678w==
|
||||||
|
|
||||||
"@types/mime@^1":
|
"@types/mime@^1":
|
||||||
version "1.3.2"
|
version "1.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a"
|
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a"
|
||||||
integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==
|
integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==
|
||||||
|
|
||||||
|
"@types/mongodb@*":
|
||||||
|
version "4.0.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/mongodb/-/mongodb-4.0.7.tgz#ebaa80c53b684ea52ccfe7721c0f5c9ef7b4f511"
|
||||||
|
integrity sha512-lPUYPpzA43baXqnd36cZ9xxorprybxXDzteVKCPAdp14ppHtFJHnXYvNpmBvtMUTb5fKXVv6sVbzo1LHkWhJlw==
|
||||||
|
dependencies:
|
||||||
|
mongodb "*"
|
||||||
|
|
||||||
|
"@types/mongoose@5.10.5":
|
||||||
|
version "5.10.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/mongoose/-/mongoose-5.10.5.tgz#0f4fb0440e8cf0213caec1e5c7b163dbd9847c56"
|
||||||
|
integrity sha512-37QMIA954T3n+HSksSNLlxZsqF8fMJu5S4dyPBod6gRxGtsXlQ9jUtL8BE8Seimv99u79eLXI3bggoCnSQ/fxQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/mongodb" "*"
|
||||||
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/node@*", "@types/node@>=13.13.4":
|
"@types/node@*", "@types/node@>=13.13.4":
|
||||||
version "16.11.7"
|
version "16.11.7"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.7.tgz#36820945061326978c42a01e56b61cd223dfdc42"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.7.tgz#36820945061326978c42a01e56b61cd223dfdc42"
|
||||||
|
@ -2643,6 +2685,13 @@
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
safe-buffer "*"
|
safe-buffer "*"
|
||||||
|
|
||||||
|
"@types/redis@^2.8.0":
|
||||||
|
version "2.8.32"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/redis/-/redis-2.8.32.tgz#1d3430219afbee10f8cfa389dad2571a05ecfb11"
|
||||||
|
integrity sha512-7jkMKxcGq9p242exlbsVzuJb57KqHRhNl4dHoQu2Y5v9bCAbtIXXH0R3HleSQW4CTOqpHIYUW3t6tpUj4BVQ+w==
|
||||||
|
dependencies:
|
||||||
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/request@^2.48.7":
|
"@types/request@^2.48.7":
|
||||||
version "2.48.8"
|
version "2.48.8"
|
||||||
resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.8.tgz#0b90fde3b655ab50976cb8c5ac00faca22f5a82c"
|
resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.8.tgz#0b90fde3b655ab50976cb8c5ac00faca22f5a82c"
|
||||||
|
@ -2653,6 +2702,16 @@
|
||||||
"@types/tough-cookie" "*"
|
"@types/tough-cookie" "*"
|
||||||
form-data "^2.5.0"
|
form-data "^2.5.0"
|
||||||
|
|
||||||
|
"@types/sequelize@*":
|
||||||
|
version "4.28.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/sequelize/-/sequelize-4.28.11.tgz#8b0c530bac4e6d73a0416a94db0de820cc4d47c3"
|
||||||
|
integrity sha512-2zeMcB5ZI+u1UwxM4sa3gLu8eSp0Gk+emTKPWXuNk3ePFo4EUYLgmIhGV6b+kYoshXpZHG3nJVMK00tuh5vEQA==
|
||||||
|
dependencies:
|
||||||
|
"@types/bluebird" "*"
|
||||||
|
"@types/continuation-local-storage" "*"
|
||||||
|
"@types/lodash" "*"
|
||||||
|
"@types/validator" "*"
|
||||||
|
|
||||||
"@types/serve-static@*":
|
"@types/serve-static@*":
|
||||||
version "1.13.10"
|
version "1.13.10"
|
||||||
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9"
|
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9"
|
||||||
|
@ -2684,6 +2743,24 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.1.tgz#8f80dd965ad81f3e1bc26d6f5c727e132721ff40"
|
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.1.tgz#8f80dd965ad81f3e1bc26d6f5c727e132721ff40"
|
||||||
integrity sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==
|
integrity sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==
|
||||||
|
|
||||||
|
"@types/validator@*":
|
||||||
|
version "13.7.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.7.1.tgz#cdab1b4779f6b1718a08de89d92d2603b71950cb"
|
||||||
|
integrity sha512-I6OUIZ5cYRk5lp14xSOAiXjWrfVoMZVjDuevBYgQDYzZIjsf2CAISpEcXOkFAtpAHbmWIDLcZObejqny/9xq5Q==
|
||||||
|
|
||||||
|
"@types/webidl-conversions@*":
|
||||||
|
version "6.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz#e33bc8ea812a01f63f90481c666334844b12a09e"
|
||||||
|
integrity sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q==
|
||||||
|
|
||||||
|
"@types/whatwg-url@^8.2.1":
|
||||||
|
version "8.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/whatwg-url/-/whatwg-url-8.2.1.tgz#f1aac222dab7c59e011663a0cb0a3117b2ef05d4"
|
||||||
|
integrity sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/node" "*"
|
||||||
|
"@types/webidl-conversions" "*"
|
||||||
|
|
||||||
"@types/yargs-parser@*":
|
"@types/yargs-parser@*":
|
||||||
version "20.2.1"
|
version "20.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129"
|
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129"
|
||||||
|
@ -3809,6 +3886,13 @@ bson@^1.1.4:
|
||||||
resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.6.tgz#fb819be9a60cd677e0853aee4ca712a785d6618a"
|
resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.6.tgz#fb819be9a60cd677e0853aee4ca712a785d6618a"
|
||||||
integrity sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==
|
integrity sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==
|
||||||
|
|
||||||
|
bson@^4.6.1:
|
||||||
|
version "4.6.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/bson/-/bson-4.6.1.tgz#2b5da517539bb0f7f3ffb54ac70a384ca899641c"
|
||||||
|
integrity sha512-I1LQ7Hz5zgwR4QquilLNZwbhPw0Apx7i7X9kGMBTsqPdml/03Q9NBtD9nt/19ahjlphktQImrnderxqpzeVDjw==
|
||||||
|
dependencies:
|
||||||
|
buffer "^5.6.0"
|
||||||
|
|
||||||
buffer-alloc-unsafe@^1.1.0:
|
buffer-alloc-unsafe@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
|
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
|
||||||
|
@ -6967,6 +7051,11 @@ ip-regex@^2.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
|
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
|
||||||
integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=
|
integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=
|
||||||
|
|
||||||
|
ip@^1.1.5:
|
||||||
|
version "1.1.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
|
||||||
|
integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
|
||||||
|
|
||||||
is-accessor-descriptor@^0.1.6:
|
is-accessor-descriptor@^0.1.6:
|
||||||
version "0.1.6"
|
version "0.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6"
|
resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6"
|
||||||
|
@ -9530,6 +9619,26 @@ moment-timezone@^0.5.31:
|
||||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
|
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
|
||||||
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
|
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
|
||||||
|
|
||||||
|
mongodb-connection-string-url@^2.4.1:
|
||||||
|
version "2.5.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.2.tgz#f075c8d529e8d3916386018b8a396aed4f16e5ed"
|
||||||
|
integrity sha512-tWDyIG8cQlI5k3skB6ywaEA5F9f5OntrKKsT/Lteub2zgwSUlhqEN2inGgBTm8bpYJf8QYBdA/5naz65XDpczA==
|
||||||
|
dependencies:
|
||||||
|
"@types/whatwg-url" "^8.2.1"
|
||||||
|
whatwg-url "^11.0.0"
|
||||||
|
|
||||||
|
mongodb@*:
|
||||||
|
version "4.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-4.4.0.tgz#3b14b9701067713d5c9afb6d6e4a86ca7b969824"
|
||||||
|
integrity sha512-1hPhutJj6yxxu0ymwsO0uEimTo+QTh3oQP6YHxmLneBFBOGydYFdnmDDuLiGWimAlMdRN9WuDXY+JGp47aeOwA==
|
||||||
|
dependencies:
|
||||||
|
bson "^4.6.1"
|
||||||
|
denque "^2.0.1"
|
||||||
|
mongodb-connection-string-url "^2.4.1"
|
||||||
|
socks "^2.6.1"
|
||||||
|
optionalDependencies:
|
||||||
|
saslprep "^1.0.3"
|
||||||
|
|
||||||
mongodb@3.6.3:
|
mongodb@3.6.3:
|
||||||
version "3.6.3"
|
version "3.6.3"
|
||||||
resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.6.3.tgz#eddaed0cc3598474d7a15f0f2a5b04848489fd05"
|
resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.6.3.tgz#eddaed0cc3598474d7a15f0f2a5b04848489fd05"
|
||||||
|
@ -11620,7 +11729,7 @@ sanitize-s3-objectkey@^0.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/sanitize-s3-objectkey/-/sanitize-s3-objectkey-0.0.1.tgz#efa9887cd45275b40234fb4bb12fc5754fe64e7e"
|
resolved "https://registry.yarnpkg.com/sanitize-s3-objectkey/-/sanitize-s3-objectkey-0.0.1.tgz#efa9887cd45275b40234fb4bb12fc5754fe64e7e"
|
||||||
integrity sha512-ZTk7aqLxy4sD40GWcYWoLfbe05XLmkKvh6vGKe13ADlei24xlezcvjgKy1qRArlaIbIMYaqK7PCalvZtulZlaQ==
|
integrity sha512-ZTk7aqLxy4sD40GWcYWoLfbe05XLmkKvh6vGKe13ADlei24xlezcvjgKy1qRArlaIbIMYaqK7PCalvZtulZlaQ==
|
||||||
|
|
||||||
saslprep@^1.0.0:
|
saslprep@^1.0.0, saslprep@^1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/saslprep/-/saslprep-1.0.3.tgz#4c02f946b56cf54297e347ba1093e7acac4cf226"
|
resolved "https://registry.yarnpkg.com/saslprep/-/saslprep-1.0.3.tgz#4c02f946b56cf54297e347ba1093e7acac4cf226"
|
||||||
integrity sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==
|
integrity sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==
|
||||||
|
@ -11876,6 +11985,11 @@ slice-ansi@^2.1.0:
|
||||||
astral-regex "^1.0.0"
|
astral-regex "^1.0.0"
|
||||||
is-fullwidth-code-point "^2.0.0"
|
is-fullwidth-code-point "^2.0.0"
|
||||||
|
|
||||||
|
smart-buffer@^4.2.0:
|
||||||
|
version "4.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae"
|
||||||
|
integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==
|
||||||
|
|
||||||
snapdragon-node@^2.0.1:
|
snapdragon-node@^2.0.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
|
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
|
||||||
|
@ -11906,6 +12020,14 @@ snapdragon@^0.8.1:
|
||||||
source-map-resolve "^0.5.0"
|
source-map-resolve "^0.5.0"
|
||||||
use "^3.1.0"
|
use "^3.1.0"
|
||||||
|
|
||||||
|
socks@^2.6.1:
|
||||||
|
version "2.6.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.2.tgz#ec042d7960073d40d94268ff3bb727dc685f111a"
|
||||||
|
integrity sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==
|
||||||
|
dependencies:
|
||||||
|
ip "^1.1.5"
|
||||||
|
smart-buffer "^4.2.0"
|
||||||
|
|
||||||
sonic-boom@^1.0.2:
|
sonic-boom@^1.0.2:
|
||||||
version "1.4.1"
|
version "1.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-1.4.1.tgz#d35d6a74076624f12e6f917ade7b9d75e918f53e"
|
resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-1.4.1.tgz#d35d6a74076624f12e6f917ade7b9d75e918f53e"
|
||||||
|
@ -12886,6 +13008,13 @@ tr46@^2.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
punycode "^2.1.1"
|
punycode "^2.1.1"
|
||||||
|
|
||||||
|
tr46@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9"
|
||||||
|
integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==
|
||||||
|
dependencies:
|
||||||
|
punycode "^2.1.1"
|
||||||
|
|
||||||
tr46@~0.0.3:
|
tr46@~0.0.3:
|
||||||
version "0.0.3"
|
version "0.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||||
|
@ -13415,6 +13544,11 @@ webidl-conversions@^6.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514"
|
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514"
|
||||||
integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==
|
integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==
|
||||||
|
|
||||||
|
webidl-conversions@^7.0.0:
|
||||||
|
version "7.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a"
|
||||||
|
integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==
|
||||||
|
|
||||||
webpack-cli@^4.9.1:
|
webpack-cli@^4.9.1:
|
||||||
version "4.9.1"
|
version "4.9.1"
|
||||||
resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3"
|
resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3"
|
||||||
|
@ -13496,6 +13630,14 @@ whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0:
|
||||||
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
|
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
|
||||||
integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
|
integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
|
||||||
|
|
||||||
|
whatwg-url@^11.0.0:
|
||||||
|
version "11.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018"
|
||||||
|
integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==
|
||||||
|
dependencies:
|
||||||
|
tr46 "^3.0.0"
|
||||||
|
webidl-conversions "^7.0.0"
|
||||||
|
|
||||||
whatwg-url@^5.0.0:
|
whatwg-url@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
|
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/string-templates",
|
"name": "@budibase/string-templates",
|
||||||
"version": "1.0.79-alpha.7",
|
"version": "1.0.79-alpha.9",
|
||||||
"description": "Handlebars wrapper for Budibase templating.",
|
"description": "Handlebars wrapper for Budibase templating.",
|
||||||
"main": "src/index.cjs",
|
"main": "src/index.cjs",
|
||||||
"module": "dist/bundle.mjs",
|
"module": "dist/bundle.mjs",
|
||||||
|
|
|
@ -18,6 +18,7 @@ module.exports.processObject = templates.processObject
|
||||||
module.exports.doesContainStrings = templates.doesContainStrings
|
module.exports.doesContainStrings = templates.doesContainStrings
|
||||||
module.exports.doesContainString = templates.doesContainString
|
module.exports.doesContainString = templates.doesContainString
|
||||||
module.exports.disableEscaping = templates.disableEscaping
|
module.exports.disableEscaping = templates.disableEscaping
|
||||||
|
module.exports.findHBSBlocks = templates.findHBSBlocks
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use vm2 to run JS scripts in a node env
|
* Use vm2 to run JS scripts in a node env
|
||||||
|
|
|
@ -3,7 +3,11 @@ const { registerAll, registerMinimum } = require("./helpers/index")
|
||||||
const processors = require("./processors")
|
const processors = require("./processors")
|
||||||
const { atob, btoa } = require("./utilities")
|
const { atob, btoa } = require("./utilities")
|
||||||
const manifest = require("../manifest.json")
|
const manifest = require("../manifest.json")
|
||||||
const { FIND_HBS_REGEX, findDoubleHbsInstances } = require("./utilities")
|
const {
|
||||||
|
FIND_HBS_REGEX,
|
||||||
|
FIND_ANY_HBS_REGEX,
|
||||||
|
findDoubleHbsInstances,
|
||||||
|
} = require("./utilities")
|
||||||
|
|
||||||
const hbsInstance = handlebars.create()
|
const hbsInstance = handlebars.create()
|
||||||
registerAll(hbsInstance)
|
registerAll(hbsInstance)
|
||||||
|
@ -310,6 +314,21 @@ module.exports.doesContainStrings = (template, strings) => {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a string, this will return any {{ binding }} or {{{ binding }}} type
|
||||||
|
* statements.
|
||||||
|
* @param {string} string The string to search within.
|
||||||
|
* @return {string[]} The found HBS blocks.
|
||||||
|
*/
|
||||||
|
module.exports.findHBSBlocks = string => {
|
||||||
|
let regexp = new RegExp(FIND_ANY_HBS_REGEX)
|
||||||
|
let matches = string.match(regexp)
|
||||||
|
if (matches == null) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
return matches
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function looks in the supplied template for handlebars instances, if they contain
|
* This function looks in the supplied template for handlebars instances, if they contain
|
||||||
* JS the JS will be decoded and then the supplied string will be looked for. For example
|
* JS the JS will be decoded and then the supplied string will be looked for. For example
|
||||||
|
|
|
@ -18,6 +18,7 @@ export const processObject = templates.processObject
|
||||||
export const doesContainStrings = templates.doesContainStrings
|
export const doesContainStrings = templates.doesContainStrings
|
||||||
export const doesContainString = templates.doesContainString
|
export const doesContainString = templates.doesContainString
|
||||||
export const disableEscaping = templates.disableEscaping
|
export const disableEscaping = templates.disableEscaping
|
||||||
|
export const findHBSBlocks = templates.findHBSBlocks
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use polyfilled vm to run JS scripts in a browser Env
|
* Use polyfilled vm to run JS scripts in a browser Env
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
const ALPHA_NUMERIC_REGEX = /^[A-Za-z0-9]+$/g
|
const ALPHA_NUMERIC_REGEX = /^[A-Za-z0-9]+$/g
|
||||||
|
|
||||||
module.exports.FIND_HBS_REGEX = /{{([^{].*?)}}/g
|
module.exports.FIND_HBS_REGEX = /{{([^{].*?)}}/g
|
||||||
|
module.exports.FIND_ANY_HBS_REGEX = /{?{{([^{].*?)}}}?/g
|
||||||
module.exports.FIND_TRIPLE_HBS_REGEX = /{{{([^{].*?)}}}/g
|
module.exports.FIND_TRIPLE_HBS_REGEX = /{{{([^{].*?)}}}/g
|
||||||
|
|
||||||
// originally this could be done with a single regex using look behinds
|
// originally this could be done with a single regex using look behinds
|
||||||
|
|
|
@ -7,6 +7,7 @@ const {
|
||||||
encodeJSBinding,
|
encodeJSBinding,
|
||||||
doesContainString,
|
doesContainString,
|
||||||
disableEscaping,
|
disableEscaping,
|
||||||
|
findHBSBlocks,
|
||||||
} = require("../src/index.cjs")
|
} = require("../src/index.cjs")
|
||||||
|
|
||||||
describe("Test that the string processing works correctly", () => {
|
describe("Test that the string processing works correctly", () => {
|
||||||
|
@ -200,3 +201,13 @@ describe("check that disabling escaping function works", () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("check find hbs blocks function", () => {
|
||||||
|
it("should find none", () => {
|
||||||
|
expect(findHBSBlocks("hello there")).toEqual([])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should find two", () => {
|
||||||
|
expect(findHBSBlocks("{{ hello }} there {{{ name }}}")).toEqual(["{{ hello }}", "{{{ name }}}"])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/worker",
|
"name": "@budibase/worker",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "1.0.79-alpha.7",
|
"version": "1.0.79-alpha.9",
|
||||||
"description": "Budibase background service",
|
"description": "Budibase background service",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -34,8 +34,8 @@
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/backend-core": "^1.0.79-alpha.7",
|
"@budibase/backend-core": "^1.0.79-alpha.9",
|
||||||
"@budibase/string-templates": "^1.0.79-alpha.7",
|
"@budibase/string-templates": "^1.0.79-alpha.9",
|
||||||
"@koa/router": "^8.0.0",
|
"@koa/router": "^8.0.0",
|
||||||
"@sentry/node": "^6.0.0",
|
"@sentry/node": "^6.0.0",
|
||||||
"@techpass/passport-openidconnect": "^0.3.0",
|
"@techpass/passport-openidconnect": "^0.3.0",
|
||||||
|
|
|
@ -1,30 +1,63 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
const path = require("path")
|
const path = require("path")
|
||||||
const fs = require("fs")
|
const fs = require("fs")
|
||||||
const { processStringSync } = require("@budibase/string-templates")
|
|
||||||
|
function processStringSync(string, env) {
|
||||||
|
let output = ""
|
||||||
|
|
||||||
|
// process if statements
|
||||||
|
let removal = false
|
||||||
|
for (let line of string.split("\n")) {
|
||||||
|
if (new RegExp(`{{\/if}}`, "g").test(line)) {
|
||||||
|
removal = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!removal) {
|
||||||
|
const match = line.match(new RegExp(`{{#if (.*)}}`))
|
||||||
|
if (match) {
|
||||||
|
const key = match[1]
|
||||||
|
// check the if statement is true
|
||||||
|
if (!env[key]) {
|
||||||
|
removal = true
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
output += line + "\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let key in env) {
|
||||||
|
// replace variables
|
||||||
|
const rgx = new RegExp(`{{\\s*${key}\\s*}}`, "g")
|
||||||
|
output = output.replace(rgx, env[key])
|
||||||
|
}
|
||||||
|
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
const Configs = {
|
const Configs = {
|
||||||
prod: {
|
prod: {
|
||||||
k8s: true,
|
|
||||||
apps: "app-service.budibase.svc.cluster.local",
|
apps: "app-service.budibase.svc.cluster.local",
|
||||||
worker: "worker-service.budibase.svc.cluster.local",
|
worker: "worker-service.budibase.svc.cluster.local",
|
||||||
minio: "minio-service.budibase.svc.cluster.local",
|
minio: "minio-service.budibase.svc.cluster.local",
|
||||||
couchdb: "budibase-prod-svc-couchdb",
|
couchdb: "budibase-prod-svc-couchdb",
|
||||||
|
resolver: "kube-dns.kube-system.svc.cluster.local"
|
||||||
},
|
},
|
||||||
preprod: {
|
preprod: {
|
||||||
k8s: true,
|
|
||||||
apps: "app-service.budibase.svc.cluster.local",
|
apps: "app-service.budibase.svc.cluster.local",
|
||||||
worker: "worker-service.budibase.svc.cluster.local",
|
worker: "worker-service.budibase.svc.cluster.local",
|
||||||
minio: "minio-service.budibase.svc.cluster.local",
|
minio: "minio-service.budibase.svc.cluster.local",
|
||||||
couchdb: "budibase-preprod-svc-couchdb",
|
couchdb: "budibase-preprod-svc-couchdb",
|
||||||
|
resolver: "kube-dns.kube-system.svc.cluster.local"
|
||||||
},
|
},
|
||||||
compose: {
|
compose: {
|
||||||
compose: true,
|
|
||||||
apps: "app-service",
|
apps: "app-service",
|
||||||
worker: "worker-service",
|
worker: "worker-service",
|
||||||
minio: "minio-service",
|
minio: "minio-service",
|
||||||
couchdb: "couchdb-service",
|
couchdb: "couchdb-service",
|
||||||
watchtower: "watchtower-service",
|
watchtower: "watchtower-service",
|
||||||
|
resolver: "127.0.0.11"
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +69,7 @@ const Commands = {
|
||||||
|
|
||||||
async function init(managementCommand) {
|
async function init(managementCommand) {
|
||||||
const config = Configs[managementCommand]
|
const config = Configs[managementCommand]
|
||||||
const hostingPath = path.join(process.cwd(), "..", "..", "hosting")
|
const hostingPath = path.join(process.cwd(), "hosting")
|
||||||
const nginxHbsPath = path.join(hostingPath, "nginx.prod.conf.hbs")
|
const nginxHbsPath = path.join(hostingPath, "nginx.prod.conf.hbs")
|
||||||
const nginxOutputPath = path.join(
|
const nginxOutputPath = path.join(
|
||||||
hostingPath,
|
hostingPath,
|
Loading…
Reference in a new issue