diff --git a/.github/workflows/deploy-cloud.yaml b/.github/workflows/deploy-cloud.yaml index 869a88a5b3..644eb5f1be 100644 --- a/.github/workflows/deploy-cloud.yaml +++ b/.github/workflows/deploy-cloud.yaml @@ -38,17 +38,6 @@ jobs: fi 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 proxy-service 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 uses: aws-actions/configure-aws-credentials@v1 with: diff --git a/.github/workflows/deploy-preprod.yml b/.github/workflows/deploy-preprod.yml index c3f690f568..cef47636ee 100644 --- a/.github/workflows/deploy-preprod.yml +++ b/.github/workflows/deploy-preprod.yml @@ -28,17 +28,6 @@ jobs: release_version=$(cat lerna.json | jq -r '.version') 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 proxy-service 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 run: | curl -H "Authorization: token ${{ secrets.GH_PERSONAL_TOKEN }}" \ diff --git a/.github/workflows/deploy-release.yml b/.github/workflows/deploy-release.yml index b37ff9cee8..cff26fd7c8 100644 --- a/.github/workflows/deploy-release.yml +++ b/.github/workflows/deploy-release.yml @@ -29,17 +29,6 @@ jobs: release_version=$(cat lerna.json | jq -r '.version') 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:release - docker tag proxy-service budibase/proxy:$RELEASE_TAG - docker push budibase/proxy:$RELEASE_TAG - env: - DOCKER_USER: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_API_KEY }} - RELEASE_TAG: k8s-release - - name: Pull values.yaml from budibase-infra run: | curl -H "Authorization: token ${{ secrets.GH_PERSONAL_TOKEN }}" \ diff --git a/.github/workflows/release-develop.yml b/.github/workflows/release-develop.yml index 21c74851e1..675707453e 100644 --- a/.github/workflows/release-develop.yml +++ b/.github/workflows/release-develop.yml @@ -26,7 +26,7 @@ env: FEATURE_PREVIEW_URL: https://budirelease.live jobs: - release: + release-images: runs-on: ubuntu-latest steps: @@ -44,19 +44,12 @@ jobs: run: yarn install:pro develop - run: yarn - - run: yarn bootstrap + - run: yarn bootstrap - run: yarn lint - run: yarn build - run: yarn build:sdk - run: yarn test - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v1 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: eu-west-1 - - name: Publish budibase packages to NPM env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} @@ -76,22 +69,25 @@ jobs: DOCKER_USER: ${{ secrets.DOCKER_USERNAME }} DOCKER_PASSWORD: ${{ secrets.DOCKER_API_KEY }} - - name: Get the latest budibase release version + deploy-to-release-env: + needs: [release-images] + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Get the current budibase release version id: version - run: | + run: | release_version=$(cat lerna.json | jq -r '.version') 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:release - docker tag proxy-service budibase/proxy:$RELEASE_TAG - docker push budibase/proxy:$RELEASE_TAG - env: - DOCKER_USER: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_API_KEY }} - RELEASE_TAG: k8s-release + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: eu-west-1 - name: Pull values.yaml from budibase-infra run: | @@ -149,3 +145,54 @@ jobs: webhook-url: ${{ secrets.PROD_DEPLOY_WEBHOOK_URL }} content: "Release Env Deployment Complete: ${{ env.RELEASE_VERSION }} deployed to Budibase Release Env." embed-title: ${{ env.RELEASE_VERSION }} + + release-helm-chart: + needs: [release-images] + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Setup Helm + uses: azure/setup-helm@v1 + id: helm-install + + # due to helm repo index issue: https://github.com/helm/helm/issues/7363 + # we need to create new package in a different dir, merge the index and move the package back + - name: Build and release helm chart + run: | + git config user.name "Budibase Helm Bot" + git config user.email "<>" + git reset --hard + git pull + mkdir sync + echo "Packaging chart to sync dir" + helm package charts/budibase --version 0.0.0-develop --app-version develop --destination sync + echo "Packaging successful" + git checkout gh-pages + echo "Indexing helm repo" + helm repo index --merge docs/index.yaml sync + mv -f sync/* docs + rm -rf sync + echo "Pushing new helm release" + git add -A + git commit -m "Helm Release: develop" + git push + + trigger-deploy-to-qa-env: + needs: [release-helm-chart] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Get the current budibase release version + id: version + run: | + release_version=$(cat lerna.json | jq -r '.version') + echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV + + - uses: passeidireto/trigger-external-workflow-action@main + env: + PAYLOAD_VERSION: ${{ env.RELEASE_VERSION }} + with: + repository: budibase/budibase-deploys + event: deploy-develop-to-qa + github_pat: ${{ secrets.GH_ACCESS_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release-selfhost.yml b/.github/workflows/release-selfhost.yml index d78180fdc7..cbf8a002f4 100644 --- a/.github/workflows/release-selfhost.yml +++ b/.github/workflows/release-selfhost.yml @@ -73,7 +73,7 @@ jobs: git config user.email "<>" git reset --hard git pull - helm package charts/budibase + helm package charts/budibase --version "$RELEASE_VERSION" --app-version "$RELEASE_VERSION" git checkout gh-pages mv *.tgz docs helm repo index docs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index de288dd7db..2a28150891 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -98,17 +98,6 @@ jobs: aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: eu-west-1 - - name: Tag and release Proxy service docker image - run: | - docker login -u $DOCKER_USER -p $DOCKER_PASSWORD - yarn build:docker:proxy:preprod - docker tag proxy-service 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 run: | curl -H "Authorization: token ${{ secrets.GH_PERSONAL_TOKEN }}" \ diff --git a/.gitignore b/.gitignore index 45bfe8b4c4..b3dc8af0d4 100644 --- a/.gitignore +++ b/.gitignore @@ -66,8 +66,6 @@ typings/ .env !qa-core/.env !hosting/.env -hosting/.generated-nginx.dev.conf -hosting/proxy/.generated-nginx.prod.conf # parcel-bundler cache (https://parceljs.org/) .cache @@ -105,7 +103,9 @@ stats.html # TypeScript cache *.tsbuildinfo + +# plugins budibase-component budibase-datasource -*.iml \ No newline at end of file +*.iml diff --git a/charts/budibase/Chart.yaml b/charts/budibase/Chart.yaml index 570aa04d8e..9d02e19506 100644 --- a/charts/budibase/Chart.yaml +++ b/charts/budibase/Chart.yaml @@ -11,8 +11,10 @@ sources: - https://github.com/Budibase/budibase - https://budibase.com type: application -version: 0.2.11 -appVersion: 1.0.214 +# populates on packaging +version: 0.0.0 +# populates on packaging +appVersion: 0.0.0 dependencies: - name: couchdb version: 3.6.1 diff --git a/charts/budibase/templates/proxy-service-deployment.yaml b/charts/budibase/templates/proxy-service-deployment.yaml index 3cde7a2388..00c12271db 100644 --- a/charts/budibase/templates/proxy-service-deployment.yaml +++ b/charts/budibase/templates/proxy-service-deployment.yaml @@ -28,11 +28,26 @@ spec: app.kubernetes.io/name: budibase-proxy spec: containers: - - image: budibase/proxy:{{ .Values.services.proxy.tag | default "k8s" }} + - image: budibase/proxy:{{ .Values.globals.appVersion }} imagePullPolicy: Always name: proxy-service ports: - containerPort: {{ .Values.services.proxy.port }} + env: + - name: APPS_UPSTREAM_URL + value: {{ tpl .Values.services.proxy.upstreams.apps . | quote }} + - name: WORKER_UPSTREAM_URL + value: {{ tpl .Values.services.proxy.upstreams.worker . | quote }} + - name: MINIO_UPSTREAM_URL + value: {{ tpl .Values.services.proxy.upstreams.minio . | quote }} + - name: COUCHDB_UPSTREAM_URL + value: {{ .Values.services.couchdb.url | default (tpl .Values.services.proxy.upstreams.couchdb .) | quote }} + - name: RESOLVER + {{ if .Values.services.proxy.resolver }} + value: {{ .Values.services.proxy.resolver }} + {{ else }} + value: kube-dns.kube-system.svc.{{ .Values.services.dns }} + {{ end }} {{ with .Values.services.proxy.resources }} resources: {{- toYaml . | nindent 10 }} diff --git a/charts/budibase/values.yaml b/charts/budibase/values.yaml index 1b2b1c3dcb..1d49a46d59 100644 --- a/charts/budibase/values.yaml +++ b/charts/budibase/values.yaml @@ -124,6 +124,11 @@ services: proxy: port: 10000 replicaCount: 1 + upstreams: + apps: 'http://app-service.{{ .Release.Namespace }}.svc.{{ .Values.services.dns }}:{{ .Values.services.apps.port }}' + worker: 'http://worker-service.{{ .Release.Namespace }}.svc.{{ .Values.services.dns }}:{{ .Values.services.worker.port }}' + minio: 'http://minio-service.{{ .Release.Namespace }}.svc.{{ .Values.services.dns }}:{{ .Values.services.objectStore.port }}' + couchdb: 'http://{{ .Release.Name }}-svc-couchdb:{{ .Values.services.couchdb.port }}' resources: {} apps: diff --git a/hosting/docker-compose.dev.yaml b/hosting/docker-compose.dev.yaml index 7322b0e8a9..1626d520b6 100644 --- a/hosting/docker-compose.dev.yaml +++ b/hosting/docker-compose.dev.yaml @@ -25,9 +25,9 @@ services: proxy-service: container_name: budi-nginx-dev restart: on-failure - image: nginx:latest + image: budibase/proxy:latest volumes: - - ./.generated-nginx.dev.conf:/etc/nginx/nginx.conf + - ./nginx.dev.conf:/etc/nginx/templates/nginx.conf.template - ./proxy/error.html:/usr/share/nginx/html/error.html ports: - "${MAIN_PORT}:10000" @@ -36,6 +36,8 @@ services: - couchdb-service extra_hosts: - "host.docker.internal:host-gateway" + environment: + - PROXY_ADDRESS=host.docker.internal couchdb-service: # platform: linux/amd64 diff --git a/hosting/docker-compose.yaml b/hosting/docker-compose.yaml index 5b2adc2665..d36937910f 100644 --- a/hosting/docker-compose.yaml +++ b/hosting/docker-compose.yaml @@ -82,6 +82,12 @@ services: environment: - PROXY_RATE_LIMIT_WEBHOOKS_PER_SECOND=10 - PROXY_RATE_LIMIT_API_PER_SECOND=20 + - APPS_UPSTREAM_URL=http://app-service:4002 + - WORKER_UPSTREAM_URL=http://worker-service:4003 + - MINIO_UPSTREAM_URL=http://minio-service:9000 + - COUCHDB_UPSTREAM_URL=http://couchdb-service:5984 + - WATCHTOWER_UPSTREAM_URL=http://watchtower-service:8080 + - RESOLVER=127.0.0.11 depends_on: - minio-service - worker-service diff --git a/hosting/nginx.dev.conf.hbs b/hosting/nginx.dev.conf similarity index 98% rename from hosting/nginx.dev.conf.hbs rename to hosting/nginx.dev.conf index 1dfaeed7ee..1ecee422cd 100644 --- a/hosting/nginx.dev.conf.hbs +++ b/hosting/nginx.dev.conf @@ -25,17 +25,17 @@ http { } upstream app-service { - server {{address}}:4001; + server ${PROXY_ADDRESS}:4001; keepalive 32; } upstream worker-service { - server {{address}}:4002; + server ${PROXY_ADDRESS}:4002; keepalive 32; } upstream builder { - server {{address}}:3000; + server ${PROXY_ADDRESS}:3000; keepalive 32; } diff --git a/hosting/proxy/Dockerfile b/hosting/proxy/Dockerfile index 68e8134750..42327be087 100644 --- a/hosting/proxy/Dockerfile +++ b/hosting/proxy/Dockerfile @@ -4,7 +4,7 @@ FROM nginx:latest # use the default nginx behaviour for *.template files which are processed with envsubst # override the output dir to output directly to /etc/nginx instead of /etc/nginx/conf.d ENV NGINX_ENVSUBST_OUTPUT_DIR=/etc/nginx -COPY .generated-nginx.prod.conf /etc/nginx/templates/nginx.conf.template +COPY nginx.prod.conf /etc/nginx/templates/nginx.conf.template # IPv6 removal needs to happen after envsubst RUN rm -rf /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh @@ -16,4 +16,11 @@ COPY error.html /usr/share/nginx/html/error.html # Default environment ENV PROXY_RATE_LIMIT_WEBHOOKS_PER_SECOND=10 -ENV PROXY_RATE_LIMIT_API_PER_SECOND=20 \ No newline at end of file +ENV PROXY_RATE_LIMIT_API_PER_SECOND=20 +# Use docker-compose values as defaults for backwards compatibility +ENV APPS_UPSTREAM_URL=http://app-service:4002 +ENV WORKER_UPSTREAM_URL=http://worker-service:4003 +ENV MINIO_UPSTREAM_URL=http://minio-service:9000 +ENV COUCHDB_UPSTREAM_URL=http://couchdb-service:5984 +ENV WATCHTOWER_UPSTREAM_URL=http://watchtower-service:8080 +ENV RESOLVER=127.0.0.11 diff --git a/hosting/nginx.prod.conf.hbs b/hosting/proxy/nginx.prod.conf similarity index 91% rename from hosting/nginx.prod.conf.hbs rename to hosting/proxy/nginx.prod.conf index cd70ce1ae2..fc2f51370b 100644 --- a/hosting/nginx.prod.conf.hbs +++ b/hosting/proxy/nginx.prod.conf @@ -23,7 +23,7 @@ http { tcp_nodelay on; server_tokens off; types_hash_max_size 2048; - resolver {{ resolver }} valid=10s ipv6=off; + resolver ${RESOLVER} valid=10s ipv6=off; # buffering client_header_buffer_size 1k; @@ -76,27 +76,23 @@ http { add_header Content-Security-Policy "${csp_default}; ${csp_script}; ${csp_style}; ${csp_object}; ${csp_base_uri}; ${csp_connect}; ${csp_font}; ${csp_frame}; ${csp_img}; ${csp_manifest}; ${csp_media}; ${csp_worker};" always; # upstreams - set $apps {{ apps }}; - set $worker {{ worker }}; - set $minio {{ minio }}; - set $couchdb {{ couchdb }}; - {{#if watchtower}} - set $watchtower {{ watchtower }}; - {{/if}} + set $apps ${APPS_UPSTREAM_URL}; + set $worker ${WORKER_UPSTREAM_URL}; + set $minio ${MINIO_UPSTREAM_URL}; + set $couchdb ${COUCHDB_UPSTREAM_URL}; + set $watchtower ${WATCHTOWER_UPSTREAM_URL}; location /app { - proxy_pass http://$apps:4002; + proxy_pass $apps; } location = / { - proxy_pass http://$apps:4002; + proxy_pass $apps; } - {{#if watchtower}} location = /v1/update { - proxy_pass http://$watchtower:8080; + proxy_pass $watchtower; } - {{/if}} location ~ ^/(builder|app_) { proxy_http_version 1.1; @@ -107,19 +103,17 @@ http { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; - proxy_pass http://$apps:4002; + proxy_pass $apps; } location ~ ^/api/(system|admin|global)/ { proxy_set_header Host $host; - - proxy_pass http://$worker:4003; + proxy_pass $worker; } location /worker/ { proxy_set_header Host $host; - - proxy_pass http://$worker:4003; + proxy_pass $worker; rewrite ^/worker/(.*)$ /$1 break; } @@ -138,7 +132,7 @@ http { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_pass http://$apps:4002; + proxy_pass $apps; } location /api/ { @@ -157,7 +151,7 @@ http { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; - proxy_pass http://$apps:4002; + proxy_pass $apps; } location /api/webhooks/ { @@ -177,11 +171,11 @@ http { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; - proxy_pass http://$apps:4002; + proxy_pass $apps; } location /db/ { - proxy_pass http://$couchdb:5984; + proxy_pass $couchdb; rewrite ^/db/(.*)$ /$1 break; } @@ -191,7 +185,7 @@ http { proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; - proxy_pass http://$apps:4002; + proxy_pass $apps; } location / { @@ -205,7 +199,7 @@ http { proxy_set_header Connection ""; chunked_transfer_encoding off; - proxy_pass http://$minio:9000; + proxy_pass $minio; } location /files/signed/ { @@ -224,7 +218,7 @@ http { proxy_set_header Connection ""; chunked_transfer_encoding off; - proxy_pass http://$minio:9000; + proxy_pass $minio; rewrite ^/files/signed/(.*)$ /$1 break; } diff --git a/lerna.json b/lerna.json index 17b8ec3cee..e0fa832023 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.2.4-alpha.7", + "version": "2.2.10-alpha.11", "npmClient": "yarn", "packages": [ "packages/*" @@ -15,4 +15,4 @@ ] } } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 5034c3b743..ac09edf5ae 100644 --- a/package.json +++ b/package.json @@ -56,15 +56,11 @@ "test:e2e:ci:record": "lerna run cy:ci:record --stream", "test:e2e:ci:notify": "lerna run cy:ci:notify", "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 && cd hosting/scripts/linux/ && ./release-to-docker-hub.sh $BUDIBASE_RELEASE_VERSION && cd -", "build:docker:pre": "lerna run build && lerna run predocker", "build:docker:proxy": "docker build hosting/proxy -t proxy-service", - "build:docker:proxy:compose": "node scripts/proxy/generateProxyConfig compose && npm run build:docker:proxy", - "build:docker:proxy:preprod": "node scripts/proxy/generateProxyConfig preprod && npm run build:docker:proxy", - "build:docker:proxy:release": "node scripts/proxy/generateProxyConfig release && 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: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 && cd hosting/scripts/linux/ && ./release-to-docker-hub.sh develop && cd -", "build:docker:airgap": "node hosting/scripts/airgapped/airgappedDockerBuild", "build:digitalocean": "cd hosting/digitalocean && ./build.sh && cd -", "build:docker:single:multiarch": "docker buildx build --platform linux/arm64,linux/amd64 -f hosting/single/Dockerfile -t budibase:latest .", @@ -88,4 +84,4 @@ "install:pro": "bash scripts/pro/install.sh", "dep:clean": "yarn clean && yarn bootstrap" } -} +} \ No newline at end of file diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 316f6f65db..78d85fc484 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "2.2.4-alpha.7", + "version": "2.2.10-alpha.11", "description": "Budibase backend core libraries used in server and worker", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -15,13 +15,15 @@ "prebuild": "rimraf dist/", "prepack": "cp package.json dist", "build": "tsc -p tsconfig.build.json", + "build:pro": "../../scripts/pro/build.sh", + "postbuild": "yarn run build:pro", "build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput", "test": "jest --coverage --maxWorkers=2", "test:watch": "jest --watchAll" }, "dependencies": { "@budibase/nano": "10.1.1", - "@budibase/types": "2.2.4-alpha.7", + "@budibase/types": "2.2.10-alpha.11", "@shopify/jest-koa-mocks": "5.0.1", "@techpass/passport-openidconnect": "0.3.2", "aws-cloudfront-sign": "2.2.0", @@ -79,4 +81,4 @@ "typescript": "4.7.3" }, "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc" -} \ No newline at end of file +} diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 6536f65dd5..be38631042 100644 --- a/packages/bbui/package.json +++ b/packages/bbui/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/bbui", "description": "A UI solution used in the different Budibase projects.", - "version": "2.2.4-alpha.7", + "version": "2.2.10-alpha.11", "license": "MPL-2.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", @@ -38,7 +38,7 @@ ], "dependencies": { "@adobe/spectrum-css-workflow-icons": "1.2.1", - "@budibase/string-templates": "2.2.4-alpha.7", + "@budibase/string-templates": "2.2.10-alpha.11", "@spectrum-css/actionbutton": "1.0.1", "@spectrum-css/actiongroup": "1.0.1", "@spectrum-css/avatar": "3.0.2", @@ -89,4 +89,4 @@ "loader-utils": "1.4.1" }, "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc" -} \ No newline at end of file +} diff --git a/packages/builder/cypress/integration/adminAndManagement/accountPortals.spec.js b/packages/builder/cypress/integration/adminAndManagement/accountPortals.spec.js index 448240f81d..7c69a5462e 100644 --- a/packages/builder/cypress/integration/adminAndManagement/accountPortals.spec.js +++ b/packages/builder/cypress/integration/adminAndManagement/accountPortals.spec.js @@ -3,17 +3,17 @@ const interact = require('../../support/interact') filterTests(["smoke", "all"], () => { context("Account Portals", () => { - + const bbUserEmail = "bbuser@test.com" - + before(() => { cy.login() cy.deleteApp("Cypress Tests") cy.createApp("Cypress Tests", false) - + // Create new user cy.wait(500) - cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 5000}) + cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 5000 }) cy.createUser(bbUserEmail) cy.contains("bbuser").click() cy.wait(500) @@ -25,18 +25,18 @@ filterTests(["smoke", "all"], () => { cy.get(interact.SPECTRUM_MENU).within(() => { cy.get(interact.SPECTRUM_MENU_ITEM).contains("Force password reset").click({ force: true }) }) - + cy.get(interact.SPECTRUM_DIALOG_GRID) - .find(interact.SPECTRUM_TEXTFIELD_INPUT).invoke('val').as('pwd') + .find(interact.SPECTRUM_TEXTFIELD_INPUT).invoke('val').as('pwd') cy.get(interact.SPECTRUM_BUTTON).contains("Reset password").click({ force: true }) - + // Login as new user and set password cy.logOut() cy.get('@pwd').then((pwd) => { cy.login(bbUserEmail, pwd) }) - + for (let i = 0; i < 2; i++) { cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).eq(i).type("test") } @@ -58,15 +58,15 @@ filterTests(["smoke", "all"], () => { cy.logoutNoAppGrid() }) - - it("should verify Admin Portal", () => { - cy.login() - // Configure user role - cy.setUserRole("bbuser", "Admin") - bbUserLogin() - // Verify available options for Admin portal - cy.get(interact.SPECTRUM_SIDENAV) + xit("should verify Admin Portal", () => { + cy.login() + // Configure user role + cy.setUserRole("bbuser", "Admin") + bbUserLogin() + + // Verify available options for Admin portal + cy.get(interact.SPECTRUM_SIDENAV) .should('contain', 'Apps') //.and('contain', 'Usage') .and('contain', 'Users') @@ -75,12 +75,12 @@ filterTests(["smoke", "all"], () => { .and('contain', 'Organisation') .and('contain', 'Theming') .and('contain', 'Update') - //.and('contain', 'Upgrade') + //.and('contain', 'Upgrade') - cy.logOut() + cy.logOut() }) - it("should verify Development Portal", () => { + xit("should verify Development Portal", () => { // Only Development access should be enabled cy.login() cy.setUserRole("bbuser", "Developer") @@ -98,7 +98,7 @@ filterTests(["smoke", "all"], () => { .and('not.contain', 'Update') .and('not.contain', 'Upgrade') - cy.logOut() + cy.logOut() }) const bbUserLogin = () => { diff --git a/packages/builder/cypress/integration/appOverview.spec.js b/packages/builder/cypress/integration/appOverview.spec.js index dafafab67a..2afc0af277 100644 --- a/packages/builder/cypress/integration/appOverview.spec.js +++ b/packages/builder/cypress/integration/appOverview.spec.js @@ -9,7 +9,7 @@ filterTests(["all"], () => { cy.createApp("Cypress Tests") }) - it("Should be accessible from the applications list", () => { + xit("Should be accessible from the applications list", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) cy.get(".appTable .title") .eq(0) @@ -27,7 +27,7 @@ filterTests(["all"], () => { }) // Find a more suitable place for this. - it("Should allow unlocking in the app list", () => { + xit("Should allow unlocking in the app list", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) cy.get(".appTable .lock-status").eq(0).contains("Locked by you").click() @@ -38,7 +38,7 @@ filterTests(["all"], () => { cy.get(".lock-status").should("not.be.visible") }) - it("Should allow unlocking in the app overview screen", () => { + xit("Should allow unlocking in the app overview screen", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) cy.get(".appTable .app-row-actions button") @@ -58,7 +58,7 @@ filterTests(["all"], () => { cy.get(".lock-status").should("not.be.visible") }) - it("Should reflect the deploy state of an app that hasn't been published.", () => { + xit("Should reflect the deploy state of an app that hasn't been published.", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) cy.get(".appTable .app-row-actions button") @@ -81,7 +81,7 @@ filterTests(["all"], () => { }) }) - it("Should reflect the app deployment state", () => { + xit("Should reflect the app deployment state", () => { cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 5000 }) cy.get(".appTable .app-row-actions button") .contains("Edit") @@ -117,7 +117,7 @@ filterTests(["all"], () => { }) }) - it("Should reflect an application that has been unpublished", () => { + xit("Should reflect an application that has been unpublished", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) cy.get(".appTable .app-row-actions button") .contains("Edit") @@ -154,7 +154,7 @@ filterTests(["all"], () => { }) }) - it("Should allow the editing of the application icon and colour", () => { + xit("Should allow the editing of the application icon and colour", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) cy.get(".appTable .app-row-actions button") .contains("Manage") @@ -196,7 +196,7 @@ filterTests(["all"], () => { }) }) - it("Should reflect the last time the application was edited", () => { + xit("Should reflect the last time the application was edited", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) cy.get(".appTable .app-row-actions button") .contains("Manage") @@ -221,7 +221,7 @@ filterTests(["all"], () => { }) }) - it("Should reflect application version is up-to-date", () => { + xit("Should reflect application version is up-to-date", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) cy.get(".appTable .app-row-actions button") .contains("Manage") @@ -302,7 +302,7 @@ filterTests(["all"], () => { }) }) - it("Should allow editing of the app details.", () => { + xit("Should allow editing of the app details.", () => { cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 5000 }) cy.get(".appTable .app-row-actions button") .contains("Manage") @@ -373,13 +373,13 @@ filterTests(["all"], () => { .contains("Copy App ID") .click({ force: true }) }) - + cy.get(".spectrum-Toast-content") - .contains("App ID copied to clipboard.") - .should("be.visible") + .contains("App ID copied to clipboard.") + .should("be.visible") }) - it("Should allow unpublishing of the application via the Unpublish link", () => { + xit("Should allow unpublishing of the application via the Unpublish link", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) cy.get(".appTable .app-row-actions button") .contains("Manage") @@ -388,7 +388,7 @@ filterTests(["all"], () => { cy.get(`[data-cy="app-status"]`).within(() => { cy.contains("Unpublish").click({ force: true }) - }) + }) cy.get("[data-cy='unpublish-modal']") .should("be.visible") @@ -399,11 +399,11 @@ filterTests(["all"], () => { cy.get(".overview-tab [data-cy='app-status']").within(() => { cy.get(".status-display").contains("Unpublished") cy.get(".status-display .icon svg[aria-label='GlobeStrike']") - .should("exist") + .should("exist") }) }) - it("Should allow deleting of the application", () => { + xit("Should allow deleting of the application", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) cy.get(".appTable .app-row-actions button") .contains("Manage") diff --git a/packages/builder/cypress/integration/createAutomation.spec.js b/packages/builder/cypress/integration/createAutomation.spec.js index 8c16f4bd22..6326691d28 100644 --- a/packages/builder/cypress/integration/createAutomation.spec.js +++ b/packages/builder/cypress/integration/createAutomation.spec.js @@ -2,13 +2,13 @@ import filterTests from "../support/filterTests" const interact = require('../support/interact') filterTests(['smoke', 'all'], () => { - context("Create a automation", () => { + xcontext("Create a automation", () => { before(() => { cy.login() cy.createTestApp() }) - it("should create a automation", () => { + xit("should create a automation", () => { cy.createTestTableWithData() cy.wait(2000) cy.contains("Automate").click() diff --git a/packages/builder/cypress/integration/createView.spec.js b/packages/builder/cypress/integration/createView.spec.js index 9adc486f70..69d3a107a5 100644 --- a/packages/builder/cypress/integration/createView.spec.js +++ b/packages/builder/cypress/integration/createView.spec.js @@ -26,13 +26,15 @@ filterTests(['smoke', 'all'], () => { cy.get("input").type("Test View") cy.get("button").contains("Create View").click({ force: true }) }) - cy.get(interact.TABLE_TITLE_H1).contains("Test View") - cy.get(interact.TITLE).then($headers => { - expect($headers).to.have.length(3) - const headers = Array.from($headers).map(header => - header.textContent.trim() - ) - expect(removeSpacing(headers)).to.deep.eq(["group", "age", "rating"]) + cy.contains(interact.TABLE_TITLE_H1, "Test View", { timeout: 10000 }) + cy.get(".table-wrapper").within(() => { + cy.get(interact.TITLE).then($headers => { + expect($headers).to.have.length(3) + const headers = Array.from($headers).map(header => + header.textContent.trim() + ) + expect(removeSpacing(headers)).to.deep.eq(["group", "age", "rating"]) + }) }) }) @@ -70,20 +72,22 @@ filterTests(['smoke', 'all'], () => { }) cy.wait(1000) - cy.get(interact.TITLE).then($headers => { - expect($headers).to.have.length(7) - const headers = Array.from($headers).map(header => - header.textContent.trim() - ) - expect(removeSpacing(headers)).to.deep.eq([ - "field", - "sum", - "min", - "max", - "count", - "sumsqr", - "avg", - ]) + cy.get(".table-wrapper").within(() => { + cy.get(interact.TITLE).then($headers => { + expect($headers).to.have.length(7) + const headers = Array.from($headers).map(header => + header.textContent.trim() + ) + expect(removeSpacing(headers)).to.deep.eq([ + "field", + "sum", + "min", + "max", + "count", + "sumsqr", + "avg", + ]) + }) }) cy.get(interact.SPECTRUM_TABLE_CELL).then($values => { let values = Array.from($values).map(header => header.textContent.trim()) diff --git a/packages/builder/cypress/integration/queryLevelTransformers.spec.js b/packages/builder/cypress/integration/queryLevelTransformers.spec.js index d16f8075f9..00cae6f417 100644 --- a/packages/builder/cypress/integration/queryLevelTransformers.spec.js +++ b/packages/builder/cypress/integration/queryLevelTransformers.spec.js @@ -14,11 +14,13 @@ filterTests(["smoke", "all"], () => { const restUrl = "https://api.openbrewerydb.org/breweries" cy.selectExternalDatasource(datasource) cy.createRestQuery("GET", restUrl, "/breweries") - cy.get(interact.SPECTRUM_TABS_ITEM).contains("Transformer").click() + cy.reload() + cy.contains(".nav-item-content", "/breweries", { timeout: 20000 }).click() + cy.contains(interact.SPECTRUM_TABS_ITEM, "Transformer", { timeout: 5000 }).click({ force: true }) // Get Transformer Function from file cy.readFile("cypress/support/queryLevelTransformerFunction.js").then( transformerFunction => { - cy.get(interact.CODEMIRROR_TEXTAREA) + cy.get(interact.CODEMIRROR_TEXTAREA, { timeout: 5000 }) // Highlight current text and overwrite with file contents .type(Cypress.platform === "darwin" ? "{cmd}a" : "{ctrl}a", { force: true, @@ -28,6 +30,7 @@ filterTests(["smoke", "all"], () => { ) // Send Query cy.intercept("**/queries/preview").as("query") + cy.get(interact.SPECTRUM_BUTTON).contains("Save").click({ force: true }) cy.get(interact.SPECTRUM_BUTTON).contains("Send").click({ force: true }) cy.wait("@query") // Assert against Status Code, body, & body rows @@ -42,7 +45,9 @@ filterTests(["smoke", "all"], () => { const restUrl = "https://api.openbrewerydb.org/breweries" cy.selectExternalDatasource(datasource) cy.createRestQuery("GET", restUrl, "/breweries") - cy.get(interact.SPECTRUM_TABS_ITEM).contains("Transformer").click() + cy.reload() + cy.contains(".nav-item-content", "/breweries", { timeout: 2000 }).click() + cy.contains(interact.SPECTRUM_TABS_ITEM, "Transformer", { timeout: 5000 }).click({ force: true }) // Get Transformer Function with Data from file cy.readFile( "cypress/support/queryLevelTransformerFunctionWithData.js" @@ -71,7 +76,9 @@ filterTests(["smoke", "all"], () => { const restUrl = "https://api.openbrewerydb.org/breweries" cy.selectExternalDatasource(datasource) cy.createRestQuery("GET", restUrl, "/breweries") - cy.get(interact.SPECTRUM_TABS_ITEM).contains("Transformer").click() + cy.reload() + cy.contains(".nav-item-content", "/breweries", { timeout: 2000 }).click() + cy.contains(interact.SPECTRUM_TABS_ITEM, "Transformer", { timeout: 5000 }).click({ force: true }) // Clear the code box and add "test" cy.get(interact.CODEMIRROR_TEXTAREA) .type(Cypress.platform === "darwin" ? "{cmd}a" : "{ctrl}a", { diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js index 278c6504f8..4c44fd6672 100644 --- a/packages/builder/cypress/support/commands.js +++ b/packages/builder/cypress/support/commands.js @@ -413,7 +413,7 @@ Cypress.Commands.add("searchForApplication", appName => { // Assumes there are no others Cypress.Commands.add("applicationInAppTable", appName => { cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 30000 }) - cy.get(".appTable", { timeout: 5000 }).within(() => { + cy.get(".appTable", { timeout: 30000 }).within(() => { cy.get(".title").contains(appName).should("exist") }) }) @@ -441,7 +441,7 @@ Cypress.Commands.add("createTable", (tableName, initialTable) => { if (!initialTable) { cy.navigateToDataSection() } - cy.get(`[data-cy="new-datasource"]`, { timeout: 2000 }).click() + cy.get(`[data-cy="new-datasource"]`, { timeout: 20000 }).click() cy.wait(2000) cy.get(".item", { timeout: 2000 }) .contains("Budibase DB") @@ -461,10 +461,7 @@ Cypress.Commands.add("createTable", (tableName, initialTable) => { cy.get(".nav-item", { timeout: 2000 }) .contains("Budibase DB") .click({ force: true }) - cy.get(".spectrum-Tabs-content", { timeout: 2000 }).should( - "contain", - tableName - ) + cy.get(".nav-item-content", { timeout: 2000 }).should("contain", tableName) }) Cypress.Commands.add("createTestTableWithData", () => { @@ -483,7 +480,7 @@ Cypress.Commands.add( // Configure column cy.get(".spectrum-Modal").within(() => { - cy.get("input").first().type(columnName).blur() + cy.get("input").first().type(columnName) // Unset table display column cy.contains("display column").click({ force: true }) @@ -795,7 +792,7 @@ Cypress.Commands.add("selectExternalDatasource", datasourceName => { // Navigates to Data Section cy.navigateToDataSection() // Open Datasource modal - cy.get(".nav").within(() => { + cy.get(".container").within(() => { cy.get("[data-cy='new-datasource']").click() }) // Clicks specified datasource & continue diff --git a/packages/builder/package.json b/packages/builder/package.json index 1ce40b1e6b..006760afca 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "2.2.4-alpha.7", + "version": "2.2.10-alpha.11", "license": "GPL-3.0", "private": true, "scripts": { @@ -71,10 +71,10 @@ } }, "dependencies": { - "@budibase/bbui": "2.2.4-alpha.7", - "@budibase/client": "2.2.4-alpha.7", - "@budibase/frontend-core": "2.2.4-alpha.7", - "@budibase/string-templates": "2.2.4-alpha.7", + "@budibase/bbui": "2.2.10-alpha.11", + "@budibase/client": "2.2.10-alpha.11", + "@budibase/frontend-core": "2.2.10-alpha.11", + "@budibase/string-templates": "2.2.10-alpha.11", "@sentry/browser": "5.19.1", "@spectrum-css/page": "^3.0.1", "@spectrum-css/vars": "^3.0.1", @@ -123,4 +123,4 @@ "vite": "^3.0.8" }, "gitHead": "115189f72a850bfb52b65ec61d932531bf327072" -} \ No newline at end of file +} diff --git a/packages/builder/src/components/backend/DataTable/modals/CreateViewModal.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateViewModal.svelte index 7e34e347e6..8f2679f874 100644 --- a/packages/builder/src/components/backend/DataTable/modals/CreateViewModal.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/CreateViewModal.svelte @@ -10,6 +10,7 @@ $: views = $tables.list.flatMap(table => Object.keys(table.views || {})) const saveView = async () => { + name = name?.trim() if (views.includes(name)) { notifications.error(`View exists with name ${name}`) return @@ -21,7 +22,7 @@ field, }) notifications.success(`View ${name} created`) - $goto(`../../view/${name}`) + $goto(`../../view/${encodeURIComponent(name)}`) } catch (error) { notifications.error("Error creating view") } diff --git a/packages/builder/src/components/backend/TableNavigator/TableNavigator.svelte b/packages/builder/src/components/backend/TableNavigator/TableNavigator.svelte index 2ad33e9477..182ac49314 100644 --- a/packages/builder/src/components/backend/TableNavigator/TableNavigator.svelte +++ b/packages/builder/src/components/backend/TableNavigator/TableNavigator.svelte @@ -36,9 +36,8 @@ indentLevel={2} icon="Remove" text={viewName} - selected={$isActive("./view/:viewName") && - $views.selected?.name === viewName} - on:click={() => $goto(`./view/${viewName}`)} + selected={$isActive("./view") && $views.selected?.name === viewName} + on:click={() => $goto(`./view/${encodeURIComponent(viewName)}`)} > { store, routify, beforeNavigate, + decode, } = options || {} if ( !urlParam || @@ -29,11 +30,23 @@ export const syncURLToState = options => { return } + // Decodes encoded URL params if required + const decodeParams = urlParams => { + if (!decode) { + return urlParams + } + let decoded = {} + Object.keys(urlParams || {}).forEach(key => { + decoded[key] = decode(urlParams[key]) + }) + return decoded + } + // We can't dynamically fetch the value of stateful routify stores so we need // to just subscribe and cache the latest versions. // We can grab their initial values as this is during component // initialisation. - let cachedParams = get(routify.params) + let cachedParams = decodeParams(get(routify.params)) let cachedGoto = get(routify.goto) let cachedRedirect = get(routify.redirect) let cachedPage = get(routify.page) @@ -77,7 +90,7 @@ export const syncURLToState = options => { // Check if new value is valid if (validate && fallbackUrl) { if (!validate(urlValue)) { - log("Invalid URL param!") + log("Invalid URL param!", urlValue) redirectUrl(fallbackUrl) return } @@ -109,7 +122,7 @@ export const syncURLToState = options => { log(`url.${urlParam} (${urlValue}) <= state.${stateKey} (${stateValue})`) if (validate && fallbackUrl) { if (!validate(stateValue)) { - log("Invalid state param!") + log("Invalid state param!", stateValue) redirectUrl(fallbackUrl) return } @@ -137,6 +150,7 @@ export const syncURLToState = options => { // Subscribe to URL changes and cache them const unsubscribeParams = routify.params.subscribe($urlParams => { + $urlParams = decodeParams($urlParams) cachedParams = $urlParams mapUrlToState($urlParams) }) diff --git a/packages/builder/src/pages/builder/app/[application]/data/view/[viewName]/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/data/view/[viewName]/_layout.svelte index 6b5c8d0fc8..2e38256d88 100644 --- a/packages/builder/src/pages/builder/app/[application]/data/view/[viewName]/_layout.svelte +++ b/packages/builder/src/pages/builder/app/[application]/data/view/[viewName]/_layout.svelte @@ -12,6 +12,7 @@ fallbackUrl: "../", store: views, routify, + decode: decodeURIComponent, }) onDestroy(stopSyncing) diff --git a/packages/builder/src/pages/builder/app/[application]/data/view/index.svelte b/packages/builder/src/pages/builder/app/[application]/data/view/index.svelte index 71ba1a81ac..7c0483fe1a 100644 --- a/packages/builder/src/pages/builder/app/[application]/data/view/index.svelte +++ b/packages/builder/src/pages/builder/app/[application]/data/view/index.svelte @@ -6,9 +6,9 @@ onMount(async () => { const { list, selected } = $views if (selected) { - $redirect(`./${selected?.name}`) + $redirect(`./${encodeURIComponent(selected?.name)}`) } else if (list?.length) { - $redirect(`./${list[0].name}`) + $redirect(`./${encodeURIComponent(list[0].name)}`) } else { $redirect("../") } diff --git a/packages/cli/package.json b/packages/cli/package.json index f06fc82f1e..a2a2d365ea 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/cli", - "version": "2.2.4-alpha.7", + "version": "2.2.10-alpha.11", "description": "Budibase CLI, for developers, self hosting and migrations.", "main": "src/index.js", "bin": { @@ -26,9 +26,9 @@ "outputPath": "build" }, "dependencies": { - "@budibase/backend-core": "2.2.4-alpha.7", - "@budibase/string-templates": "2.2.4-alpha.7", - "@budibase/types": "2.2.4-alpha.7", + "@budibase/backend-core": "2.2.10-alpha.11", + "@budibase/string-templates": "2.2.10-alpha.11", + "@budibase/types": "2.2.10-alpha.11", "axios": "0.21.2", "chalk": "4.1.0", "cli-progress": "3.11.2", @@ -54,4 +54,4 @@ "eslint": "^7.20.0", "renamer": "^4.0.0" } -} \ No newline at end of file +} diff --git a/packages/client/package.json b/packages/client/package.json index b65b14957c..6ebfa1e981 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "2.2.4-alpha.7", + "version": "2.2.10-alpha.11", "license": "MPL-2.0", "module": "dist/budibase-client.js", "main": "dist/budibase-client.js", @@ -19,9 +19,9 @@ "dev:builder": "rollup -cw" }, "dependencies": { - "@budibase/bbui": "2.2.4-alpha.7", - "@budibase/frontend-core": "2.2.4-alpha.7", - "@budibase/string-templates": "2.2.4-alpha.7", + "@budibase/bbui": "2.2.10-alpha.11", + "@budibase/frontend-core": "2.2.10-alpha.11", + "@budibase/string-templates": "2.2.10-alpha.11", "@spectrum-css/button": "^3.0.3", "@spectrum-css/card": "^3.0.3", "@spectrum-css/divider": "^1.0.3", @@ -63,4 +63,4 @@ "loader-utils": "1.4.1" }, "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc" -} \ No newline at end of file +} diff --git a/packages/frontend-core/package.json b/packages/frontend-core/package.json index f34494ef58..39ae3951cb 100644 --- a/packages/frontend-core/package.json +++ b/packages/frontend-core/package.json @@ -1,13 +1,13 @@ { "name": "@budibase/frontend-core", - "version": "2.2.4-alpha.7", + "version": "2.2.10-alpha.11", "description": "Budibase frontend core libraries used in builder and client", "author": "Budibase", "license": "MPL-2.0", "svelte": "src/index.js", "dependencies": { - "@budibase/bbui": "2.2.4-alpha.7", + "@budibase/bbui": "2.2.10-alpha.11", "lodash": "^4.17.21", "svelte": "^3.46.2" } -} \ No newline at end of file +} diff --git a/packages/frontend-core/src/api/views.js b/packages/frontend-core/src/api/views.js index 237a66bc13..1d710c5171 100644 --- a/packages/frontend-core/src/api/views.js +++ b/packages/frontend-core/src/api/views.js @@ -16,8 +16,8 @@ export const buildViewEndpoints = API => ({ params.set("group", groupBy) } const QUERY_VIEW_URL = field - ? `/api/views/${name}?${params}` - : `/api/views/${name}` + ? `/api/views/${encodeURIComponent(name)}?${params}` + : `/api/views/${encodeURIComponent(name)}` return await API.get({ url: QUERY_VIEW_URL }) }, @@ -53,7 +53,7 @@ export const buildViewEndpoints = API => ({ */ deleteView: async viewName => { return await API.delete({ - url: `/api/views/${viewName}`, + url: `/api/views/${encodeURIComponent(viewName)}`, }) }, }) diff --git a/packages/sdk/package.json b/packages/sdk/package.json index cca8bbd60e..d48e3bf863 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/sdk", - "version": "2.2.4-alpha.7", + "version": "2.2.10-alpha.11", "description": "Budibase Public API SDK", "author": "Budibase", "license": "MPL-2.0", @@ -20,4 +20,4 @@ "rollup-plugin-polyfill-node": "^0.8.0", "rollup-plugin-terser": "^7.0.2" } -} \ No newline at end of file +} diff --git a/packages/server/package.json b/packages/server/package.json index c95da1c592..4fd4d9265c 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "2.2.4-alpha.7", + "version": "2.2.10-alpha.11", "description": "Budibase Web Server", "main": "src/index.ts", "repository": { @@ -43,11 +43,11 @@ "license": "GPL-3.0", "dependencies": { "@apidevtools/swagger-parser": "10.0.3", - "@budibase/backend-core": "2.2.4-alpha.7", - "@budibase/client": "2.2.4-alpha.7", - "@budibase/pro": "2.2.4-alpha.7", - "@budibase/string-templates": "2.2.4-alpha.7", - "@budibase/types": "2.2.4-alpha.7", + "@budibase/backend-core": "2.2.10-alpha.11", + "@budibase/client": "2.2.10-alpha.11", + "@budibase/pro": "2.2.10-alpha.11", + "@budibase/string-templates": "2.2.10-alpha.11", + "@budibase/types": "2.2.10-alpha.11", "@bull-board/api": "3.7.0", "@bull-board/koa": "3.9.4", "@elastic/elasticsearch": "7.10.0", @@ -168,4 +168,4 @@ "oracledb": "5.3.0" }, "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc" -} \ No newline at end of file +} diff --git a/packages/server/scripts/dev/manage.js b/packages/server/scripts/dev/manage.js index e06c6308f8..80f21cd043 100644 --- a/packages/server/scripts/dev/manage.js +++ b/packages/server/scripts/dev/manage.js @@ -2,12 +2,6 @@ const compose = require("docker-compose") const path = require("path") const fs = require("fs") -const isWsl = require("is-wsl") -const { processStringSync } = require("@budibase/string-templates") - -function isLinux() { - return !isWsl && process.platform !== "darwin" && process.platform !== "win32" -} // This script wraps docker-compose allowing you to manage your dev infrastructure with simple commands. const CONFIG = { @@ -23,16 +17,6 @@ const Commands = { } async function init() { - // generate nginx file, always do this incase it has changed - const hostingPath = path.join(process.cwd(), "..", "..", "hosting") - const nginxHbsPath = path.join(hostingPath, "nginx.dev.conf.hbs") - const nginxOutputPath = path.join(hostingPath, ".generated-nginx.dev.conf") - const contents = fs.readFileSync(nginxHbsPath, "utf8") - const config = { - address: isLinux() ? "172.17.0.1" : "host.docker.internal", - } - fs.writeFileSync(nginxOutputPath, processStringSync(contents, config)) - const envFilePath = path.join(process.cwd(), ".env") if (!fs.existsSync(envFilePath)) { const envFileJson = { diff --git a/packages/server/src/api/controllers/application.ts b/packages/server/src/api/controllers/application.ts index e227df1a58..06e7dc8a57 100644 --- a/packages/server/src/api/controllers/application.ts +++ b/packages/server/src/api/controllers/application.ts @@ -50,7 +50,6 @@ import { } from "@budibase/types" import { BASE_LAYOUT_PROP_IDS } from "../../constants/layouts" import sdk from "../../sdk" -import { getDB } from "@budibase/backend-core/src/db" // utility function, need to do away with this async function getLayouts() { diff --git a/packages/server/src/api/controllers/row/internal.ts b/packages/server/src/api/controllers/row/internal.ts index 2b2b1b8b36..9bfdff24ea 100644 --- a/packages/server/src/api/controllers/row/internal.ts +++ b/packages/server/src/api/controllers/row/internal.ts @@ -187,7 +187,7 @@ export async function save(ctx: UserCtx) { } export async function fetchView(ctx: Ctx) { - const viewName = ctx.params.viewName + const viewName = decodeURIComponent(ctx.params.viewName) // if this is a table view being looked for just transfer to that if (viewName.startsWith(DocumentType.TABLE)) { diff --git a/packages/server/src/api/controllers/view/index.ts b/packages/server/src/api/controllers/view/index.ts index 17c3ee301d..932823d172 100644 --- a/packages/server/src/api/controllers/view/index.ts +++ b/packages/server/src/api/controllers/view/index.ts @@ -113,7 +113,7 @@ async function handleViewEvents(existingView: View, newView: View) { export async function destroy(ctx: BBContext) { const db = context.getAppDB() - const viewName = decodeURI(ctx.params.viewName) + const viewName = decodeURIComponent(ctx.params.viewName) const view = await deleteView(viewName) const table = await db.get(view.meta.tableId) delete table.views[viewName] @@ -124,7 +124,7 @@ export async function destroy(ctx: BBContext) { } export async function exportView(ctx: BBContext) { - const viewName = decodeURI(ctx.query.view as string) + const viewName = decodeURIComponent(ctx.query.view as string) const view = await getView(viewName) const format = ctx.query.format as string diff --git a/packages/server/src/integrations/base/sql.ts b/packages/server/src/integrations/base/sql.ts index 43ebc8b1dd..a2318eff12 100644 --- a/packages/server/src/integrations/base/sql.ts +++ b/packages/server/src/integrations/base/sql.ts @@ -313,7 +313,8 @@ class InternalBuilder { addRelationships( query: KnexQuery, fromTable: string, - relationships: RelationshipsJson[] | undefined + relationships: RelationshipsJson[] | undefined, + schema: string | undefined ): KnexQuery { if (!relationships) { return query @@ -337,9 +338,13 @@ class InternalBuilder { } for (let [key, relationships] of Object.entries(tableSets)) { const { toTable, throughTable } = JSON.parse(key) + const toTableWithSchema = schema ? `${schema}.${toTable}` : toTable + const throughTableWithSchema = schema + ? `${schema}.${throughTable}` + : throughTable if (!throughTable) { // @ts-ignore - query = query.leftJoin(toTable, function () { + query = query.leftJoin(toTableWithSchema, function () { for (let relationship of relationships) { const from = relationship.from, to = relationship.to @@ -350,7 +355,7 @@ class InternalBuilder { } else { query = query // @ts-ignore - .leftJoin(throughTable, function () { + .leftJoin(throughTableWithSchema, function () { for (let relationship of relationships) { const fromPrimary = relationship.fromPrimary const from = relationship.from @@ -362,7 +367,7 @@ class InternalBuilder { ) } }) - .leftJoin(toTable, function () { + .leftJoin(toTableWithSchema, function () { for (let relationship of relationships) { const toPrimary = relationship.toPrimary const to = relationship.to @@ -456,7 +461,12 @@ class InternalBuilder { preQuery = this.addSorting(preQuery, json) } // handle joins - query = this.addRelationships(preQuery, tableName, relationships) + query = this.addRelationships( + preQuery, + tableName, + relationships, + endpoint.schema + ) return this.addFilters(query, filters, { relationship: true }) } diff --git a/packages/server/src/integrations/tests/sql.spec.ts b/packages/server/src/integrations/tests/sql.spec.ts index 421b8535d4..2e45f0754b 100644 --- a/packages/server/src/integrations/tests/sql.spec.ts +++ b/packages/server/src/integrations/tests/sql.spec.ts @@ -51,6 +51,72 @@ function generateDeleteJson(table = TABLE_NAME, filters = {}) { } } +function generateRelationshipJson(config: { schema?: string } = {}) { + return { + endpoint: { + datasourceId: "Postgres", + entityId: "brands", + operation: "READ", + schema: config.schema, + }, + resource: { + fields: [ + "brands.brand_id", + "brands.brand_name", + "products.product_id", + "products.product_name", + "products.brand_id", + ], + }, + filters: {}, + sort: {}, + paginate: {}, + relationships: [ + { + from: "brand_id", + to: "brand_id", + tableName: "products", + column: "products", + }, + ], + extra: { idFilter: {} }, + } +} + +function generateManyRelationshipJson(config: { schema?: string } = {}) { + return { + endpoint: { + datasourceId: "Postgres", + entityId: "stores", + operation: "READ", + schema: config.schema, + }, + resource: { + fields: [ + "stores.store_id", + "stores.store_name", + "products.product_id", + "products.product_name", + ], + }, + filters: {}, + sort: {}, + paginate: {}, + relationships: [ + { + from: "store_id", + to: "product_id", + tableName: "products", + column: "products", + through: "stocks", + fromPrimary: "store_id", + toPrimary: "product_id", + }, + ], + extra: { idFilter: {} }, + } +} + describe("SQL query builder", () => { const limit = 500 const client = SqlClient.POSTGRES @@ -425,4 +491,30 @@ describe("SQL query builder", () => { sql: `select * from (select * from \"${TABLE_NAME}\" where \"${TABLE_NAME}\".\"age\"::jsonb ?| array [20,25] and \"${TABLE_NAME}\".\"name\"::jsonb ?| array ['John','Mary'] limit $1) as \"${TABLE_NAME}\"`, }) }) + + it("should add the schema to the LEFT JOIN", () => { + const query = sql._query(generateRelationshipJson({ schema: "production" })) + expect(query).toEqual({ + bindings: [500, 5000], + sql: `select "brands"."brand_id" as "brands.brand_id", "brands"."brand_name" as "brands.brand_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name", "products"."brand_id" as "products.brand_id" from (select * from "production"."brands" limit $1) as "brands" left join "production"."products" on "brands"."brand_id" = "products"."brand_id" limit $2`, + }) + }) + + it("should handle if the schema is not present when doing a LEFT JOIN", () => { + const query = sql._query(generateRelationshipJson()) + expect(query).toEqual({ + bindings: [500, 5000], + sql: `select "brands"."brand_id" as "brands.brand_id", "brands"."brand_name" as "brands.brand_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name", "products"."brand_id" as "products.brand_id" from (select * from "brands" limit $1) as "brands" left join "products" on "brands"."brand_id" = "products"."brand_id" limit $2`, + }) + }) + + it("should add the schema to both the toTable and throughTable in many-to-many join", () => { + const query = sql._query( + generateManyRelationshipJson({ schema: "production" }) + ) + expect(query).toEqual({ + bindings: [500, 5000], + sql: `select "stores"."store_id" as "stores.store_id", "stores"."store_name" as "stores.store_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name" from (select * from "production"."stores" limit $1) as "stores" left join "production"."stocks" on "stores"."store_id" = "stocks"."store_id" left join "production"."products" on "products"."product_id" = "stocks"."product_id" limit $2`, + }) + }) }) diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock index 6f5a25acbd..f65129c3d1 100644 --- a/packages/server/yarn.lock +++ b/packages/server/yarn.lock @@ -1273,13 +1273,13 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@2.2.4-alpha.7": - version "2.2.4-alpha.7" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.2.4-alpha.7.tgz#24cb6e969918bd3f3f3c8f7bf0371369139a92ef" - integrity sha512-n4ItEFWeDKYKlll0pCjh+A9VfR45Av9U3pjQ6tfrzfl8LeK4pIH/GUAqoT8cMu7S37fN0xMpZ7KD+D1rKbepqQ== +"@budibase/backend-core@2.2.10-alpha.11": + version "2.2.10-alpha.11" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.2.10-alpha.11.tgz#0acafccdb2031a5b1b162d768eb0f3bf5fba7fa2" + integrity sha512-OycvSwklN6O2zJCCKKWaJd6Ncq7a0lh9+x15RFaq3RhDMstfbN1yCQKET+65AKt4GE8Z5Lv+OYsvrsbrNdmUqg== dependencies: "@budibase/nano" "10.1.1" - "@budibase/types" "2.2.4-alpha.7" + "@budibase/types" "2.2.10-alpha.11" "@shopify/jest-koa-mocks" "5.0.1" "@techpass/passport-openidconnect" "0.3.2" aws-cloudfront-sign "2.2.0" @@ -1373,13 +1373,13 @@ qs "^6.11.0" tough-cookie "^4.1.2" -"@budibase/pro@2.2.4-alpha.7": - version "2.2.4-alpha.7" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.2.4-alpha.7.tgz#47768c857ee06122411f70b70741d9852a492f71" - integrity sha512-ZKkg68BouP+jAy16rzLiq90OjQmvXOZNe5BAV0d0ni1xw3eYSlIJxbEHAhLf7sQkhLAS/ZqGsLYMP7B//RpvcQ== +"@budibase/pro@2.2.10-alpha.11": + version "2.2.10-alpha.11" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.2.10-alpha.11.tgz#c0dc6d861ee4d7bddee2f815abc19fccfcb98d0c" + integrity sha512-yw5w6074CK4Dt7qEucpu/TDEzSqKdc+G5DIGwa4lc53DmYrvsT1Z8T/YmnvzMqz8p1auizJUQarGDjrXPpEnfg== dependencies: - "@budibase/backend-core" "2.2.4-alpha.7" - "@budibase/types" "2.2.4-alpha.7" + "@budibase/backend-core" "2.2.10-alpha.11" + "@budibase/types" "2.2.10-alpha.11" "@koa/router" "8.0.8" bull "4.10.1" joi "17.6.0" @@ -1404,10 +1404,10 @@ svelte-apexcharts "^1.0.2" svelte-flatpickr "^3.1.0" -"@budibase/types@2.2.4-alpha.7": - version "2.2.4-alpha.7" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.4-alpha.7.tgz#65bf5183d496a0e4088ceea0aadad61c164cc8a2" - integrity sha512-UyMa6rdmWlMbnH6sSA1XHg68ojcOd2K5w09TV0FAF4tBOcSoQgzz04ufYqR4cjg/MNyk0x3ZwlNkox5WekKBQQ== +"@budibase/types@2.2.10-alpha.11": + version "2.2.10-alpha.11" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.10-alpha.11.tgz#49986cdaca3c074eb500750905029b86cb0ca057" + integrity sha512-vm0JFxTuOtMdE7dFp2q04q998JRxSsGM0ckccWnKtKNFR8xWZE2J4UsPZSEzCtogHqrZFUV2hvVqeO3YFkTXQw== "@bull-board/api@3.7.0": version "3.7.0" diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index 5e2d9d6fa2..5be3da6c26 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "2.2.4-alpha.7", + "version": "2.2.10-alpha.11", "description": "Handlebars wrapper for Budibase templating.", "main": "src/index.cjs", "module": "dist/bundle.mjs", @@ -47,4 +47,4 @@ "typescript": "4.7.3" }, "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc" -} \ No newline at end of file +} diff --git a/packages/types/package.json b/packages/types/package.json index e956fc125f..785c363de0 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/types", - "version": "2.2.4-alpha.7", + "version": "2.2.10-alpha.11", "description": "Budibase types", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -14,12 +14,12 @@ "jest": {}, "devDependencies": { "@budibase/nano": "10.1.1", - "@types/formidable": "^1.0.31", "@types/json5": "2.2.0", "@types/koa": "2.13.4", "@types/node": "14.18.20", "@types/pouchdb": "6.4.0", + "koa-body": "4.2.0", "rimraf": "3.0.2", "typescript": "4.7.3" } -} \ No newline at end of file +} diff --git a/packages/types/yarn.lock b/packages/types/yarn.lock index bc22fdf93c..4acf3737a0 100644 --- a/packages/types/yarn.lock +++ b/packages/types/yarn.lock @@ -364,6 +364,11 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + call-bind@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -372,6 +377,16 @@ call-bind@^1.0.0: function-bind "^1.1.1" get-intrinsic "^1.0.2" +co-body@^5.1.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/co-body/-/co-body-5.2.0.tgz#5a0a658c46029131e0e3a306f67647302f71c124" + integrity sha512-sX/LQ7LqUhgyaxzbe7IqwPeTr2yfpfUIQ/dgpKo6ZI4y4lpQA0YxAomWIY+7I7rHWcG02PG+OuPREzMW/5tszQ== + dependencies: + inflation "^2.0.0" + qs "^6.4.0" + raw-body "^2.2.0" + type-is "^1.6.14" + combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -396,6 +411,11 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + follow-redirects@^1.15.0: version "1.15.2" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" @@ -410,6 +430,11 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +formidable@^1.1.1: + version "1.2.6" + resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.6.tgz#d2a51d60162bbc9b4a055d8457a7c75315d1a168" + integrity sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ== + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -460,6 +485,29 @@ http-cookie-agent@^4.0.2: dependencies: agent-base "^6.0.2" +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +inflation@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/inflation/-/inflation-2.0.0.tgz#8b417e47c28f925a45133d914ca1fd389107f30f" + integrity sha512-m3xv4hJYR2oXw4o4Y5l6P5P16WYmazYof+el6Al3f+YlggGj6qT9kImBAnzDelRALnP5d3h4jGBPKzYCizjZZw== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -468,7 +516,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2: +inherits@2, inherits@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -478,12 +526,26 @@ json5@*: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== +koa-body@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/koa-body/-/koa-body-4.2.0.tgz#37229208b820761aca5822d14c5fc55cee31b26f" + integrity sha512-wdGu7b9amk4Fnk/ytH8GuWwfs4fsB5iNkY8kZPpgQVb04QZSv85T0M8reb+cJmvLE8cjPYvBzRikD3s6qz8OoA== + dependencies: + "@types/formidable" "^1.0.31" + co-body "^5.1.1" + formidable "^1.1.1" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12: +mime-types@^2.1.12, mime-types@~2.1.24: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -539,7 +601,7 @@ punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -qs@^6.11.0: +qs@^6.11.0, qs@^6.4.0: version "6.11.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== @@ -551,6 +613,16 @@ querystringify@^2.1.1: resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== +raw-body@^2.2.0: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" @@ -563,6 +635,16 @@ rimraf@3.0.2: dependencies: glob "^7.1.3" +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -572,6 +654,16 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + tough-cookie@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" @@ -582,6 +674,14 @@ tough-cookie@^4.1.2: universalify "^0.2.0" url-parse "^1.5.3" +type-is@^1.6.14: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + typescript@4.7.3: version "4.7.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.3.tgz#8364b502d5257b540f9de4c40be84c98e23a129d" @@ -592,6 +692,11 @@ universalify@^0.2.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== +unpipe@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + url-parse@^1.5.3: version "1.5.10" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" diff --git a/packages/worker/package.json b/packages/worker/package.json index cbad812bb3..3428db54dc 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/worker", "email": "hi@budibase.com", - "version": "2.2.4-alpha.7", + "version": "2.2.10-alpha.11", "description": "Budibase background service", "main": "src/index.ts", "repository": { @@ -36,10 +36,10 @@ "author": "Budibase", "license": "GPL-3.0", "dependencies": { - "@budibase/backend-core": "2.2.4-alpha.7", - "@budibase/pro": "2.2.4-alpha.7", - "@budibase/string-templates": "2.2.4-alpha.7", - "@budibase/types": "2.2.4-alpha.7", + "@budibase/backend-core": "2.2.10-alpha.11", + "@budibase/pro": "2.2.10-alpha.11", + "@budibase/string-templates": "2.2.10-alpha.11", + "@budibase/types": "2.2.10-alpha.11", "@koa/router": "8.0.8", "@sentry/node": "6.17.7", "@techpass/passport-openidconnect": "0.3.2", @@ -96,4 +96,4 @@ "update-dotenv": "1.1.1" }, "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc" -} \ No newline at end of file +} diff --git a/packages/worker/yarn.lock b/packages/worker/yarn.lock index 5a1a31207c..0c30660e1c 100644 --- a/packages/worker/yarn.lock +++ b/packages/worker/yarn.lock @@ -470,13 +470,13 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@2.2.4-alpha.7": - version "2.2.4-alpha.7" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.2.4-alpha.7.tgz#24cb6e969918bd3f3f3c8f7bf0371369139a92ef" - integrity sha512-n4ItEFWeDKYKlll0pCjh+A9VfR45Av9U3pjQ6tfrzfl8LeK4pIH/GUAqoT8cMu7S37fN0xMpZ7KD+D1rKbepqQ== +"@budibase/backend-core@2.2.10-alpha.11": + version "2.2.10-alpha.11" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.2.10-alpha.11.tgz#0acafccdb2031a5b1b162d768eb0f3bf5fba7fa2" + integrity sha512-OycvSwklN6O2zJCCKKWaJd6Ncq7a0lh9+x15RFaq3RhDMstfbN1yCQKET+65AKt4GE8Z5Lv+OYsvrsbrNdmUqg== dependencies: "@budibase/nano" "10.1.1" - "@budibase/types" "2.2.4-alpha.7" + "@budibase/types" "2.2.10-alpha.11" "@shopify/jest-koa-mocks" "5.0.1" "@techpass/passport-openidconnect" "0.3.2" aws-cloudfront-sign "2.2.0" @@ -520,23 +520,23 @@ qs "^6.11.0" tough-cookie "^4.1.2" -"@budibase/pro@2.2.4-alpha.7": - version "2.2.4-alpha.7" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.2.4-alpha.7.tgz#47768c857ee06122411f70b70741d9852a492f71" - integrity sha512-ZKkg68BouP+jAy16rzLiq90OjQmvXOZNe5BAV0d0ni1xw3eYSlIJxbEHAhLf7sQkhLAS/ZqGsLYMP7B//RpvcQ== +"@budibase/pro@2.2.10-alpha.11": + version "2.2.10-alpha.11" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.2.10-alpha.11.tgz#c0dc6d861ee4d7bddee2f815abc19fccfcb98d0c" + integrity sha512-yw5w6074CK4Dt7qEucpu/TDEzSqKdc+G5DIGwa4lc53DmYrvsT1Z8T/YmnvzMqz8p1auizJUQarGDjrXPpEnfg== dependencies: - "@budibase/backend-core" "2.2.4-alpha.7" - "@budibase/types" "2.2.4-alpha.7" + "@budibase/backend-core" "2.2.10-alpha.11" + "@budibase/types" "2.2.10-alpha.11" "@koa/router" "8.0.8" bull "4.10.1" joi "17.6.0" jsonwebtoken "8.5.1" node-fetch "^2.6.1" -"@budibase/types@2.2.4-alpha.7": - version "2.2.4-alpha.7" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.4-alpha.7.tgz#65bf5183d496a0e4088ceea0aadad61c164cc8a2" - integrity sha512-UyMa6rdmWlMbnH6sSA1XHg68ojcOd2K5w09TV0FAF4tBOcSoQgzz04ufYqR4cjg/MNyk0x3ZwlNkox5WekKBQQ== +"@budibase/types@2.2.10-alpha.11": + version "2.2.10-alpha.11" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.10-alpha.11.tgz#49986cdaca3c074eb500750905029b86cb0ca057" + integrity sha512-vm0JFxTuOtMdE7dFp2q04q998JRxSsGM0ckccWnKtKNFR8xWZE2J4UsPZSEzCtogHqrZFUV2hvVqeO3YFkTXQw== "@cspotcode/source-map-support@^0.8.0": version "0.8.1" diff --git a/scripts/pro/build.sh b/scripts/pro/build.sh new file mode 100755 index 0000000000..b03d85a0d0 --- /dev/null +++ b/scripts/pro/build.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# This script is designed for building the pro repo after the backend-core build has completed. +# This ensures that any changes in core that are required by pro are done in the correct order. + +set -e + +# Go to parent of budibase +cd ../../../ + +if [[ -d "budibase-pro" ]]; then + cd budibase-pro + echo "Building pro" + yarn build +fi \ No newline at end of file diff --git a/scripts/pro/install.sh b/scripts/pro/install.sh index ee80bf9e0d..d6662d6341 100755 --- a/scripts/pro/install.sh +++ b/scripts/pro/install.sh @@ -35,5 +35,5 @@ if [[ -d "budibase-pro" ]]; then git pull echo "Initializing pro repo..." - yarn setup + yarn fi \ No newline at end of file diff --git a/scripts/proxy/generateProxyConfig.js b/scripts/proxy/generateProxyConfig.js deleted file mode 100644 index e30daf6156..0000000000 --- a/scripts/proxy/generateProxyConfig.js +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env node -const path = require("path") -const fs = require("fs") - -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 = { - prod: { - apps: "app-service.budibase.svc.cluster.local", - worker: "worker-service.budibase.svc.cluster.local", - minio: "minio-service.budibase.svc.cluster.local", - couchdb: "budibase-prod-svc-couchdb", - resolver: "kube-dns.kube-system.svc.cluster.local" - }, - preprod: { - apps: "app-service.budibase.svc.cluster.local", - worker: "worker-service.budibase.svc.cluster.local", - minio: "minio-service.budibase.svc.cluster.local", - couchdb: "budibase-preprod-svc-couchdb", - resolver: "kube-dns.kube-system.svc.cluster.local" - }, - release: { - apps: "app-service.budibase.svc.cluster.local", - worker: "worker-service.budibase.svc.cluster.local", - minio: "minio-service.budibase.svc.cluster.local", - couchdb: "budibase-release-svc-couchdb", - resolver: "kube-dns.kube-system.svc.cluster.local" - }, - compose: { - apps: "app-service", - worker: "worker-service", - minio: "minio-service", - couchdb: "couchdb-service", - watchtower: "watchtower-service", - resolver: "127.0.0.11" - }, -} - -const Commands = { - Prod: "prod", - Preprod: "preprod", - Release: "release", - Compose: "compose", -} - -async function init(managementCommand) { - const config = Configs[managementCommand] - const hostingPath = path.join(process.cwd(), "hosting") - const nginxHbsPath = path.join(hostingPath, "nginx.prod.conf.hbs") - const nginxOutputPath = path.join( - hostingPath, - "proxy", - ".generated-nginx.prod.conf" - ) - const contents = fs.readFileSync(nginxHbsPath, "utf8") - fs.writeFileSync(nginxOutputPath, processStringSync(contents, config)) -} - -const managementCommand = process.argv.slice(2)[0] - -if ( - !managementCommand || - !Object.values(Commands).some(command => managementCommand === command) -) { - throw new Error( - "You must supply either a 'compose', 'preprod' or 'prod' commmand to generate an NGINX config." - ) -} - -init(managementCommand) - .then(() => { - console.log("Done! 🎉") - }) - .catch(err => { - console.error( - "Something went wrong while creating the nginx configuration", - err.message - ) - })