diff --git a/hosting/couchdb/Dockerfile b/hosting/couchdb/Dockerfile index f83df7038b..36abc2dd19 100644 --- a/hosting/couchdb/Dockerfile +++ b/hosting/couchdb/Dockerfile @@ -1,4 +1,101 @@ -FROM couchdb:3.2.1 +# Modified from https://github.com/apache/couchdb-docker/blob/main/3.3.3/Dockerfile +# +# Everything in this `base` image is adapted from the official `couchdb` image's +# Dockerfile. Only modifications related to upgrading from Debian bullseye to +# bookworm have been included. The `runner` image contains Budibase's +# customisations to the image, e.g. adding Clouseau. +FROM node:20-slim AS base + +# Add CouchDB user account to make sure the IDs are assigned consistently +RUN groupadd -g 5984 -r couchdb && useradd -u 5984 -d /opt/couchdb -g couchdb couchdb + +# be sure GPG and apt-transport-https are available and functional +RUN set -ex; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + apt-transport-https \ + ca-certificates \ + dirmngr \ + gnupg \ + ; \ + rm -rf /var/lib/apt/lists/* + +# grab tini for signal handling and zombie reaping +# see https://github.com/apache/couchdb-docker/pull/28#discussion_r141112407 +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends tini; \ + rm -rf /var/lib/apt/lists/*; \ + tini --version + +# http://docs.couchdb.org/en/latest/install/unix.html#installing-the-apache-couchdb-packages +ENV GPG_COUCH_KEY \ +# gpg: rsa8192 205-01-19 The Apache Software Foundation (Package repository signing key) + 390EF70BB1EA12B2773962950EE62FB37A00258D +RUN set -eux; \ + apt-get update; \ + apt-get install -y curl; \ + export GNUPGHOME="$(mktemp -d)"; \ + curl -fL -o keys.asc https://couchdb.apache.org/repo/keys.asc; \ + gpg --batch --import keys.asc; \ + gpg --batch --export "${GPG_COUCH_KEY}" > /usr/share/keyrings/couchdb-archive-keyring.gpg; \ + command -v gpgconf && gpgconf --kill all || :; \ + rm -rf "$GNUPGHOME"; \ + apt-key list; \ + apt purge -y --autoremove curl; \ + rm -rf /var/lib/apt/lists/* + +ENV COUCHDB_VERSION 3.3.3 + +RUN . /etc/os-release; \ + echo "deb [signed-by=/usr/share/keyrings/couchdb-archive-keyring.gpg] https://apache.jfrog.io/artifactory/couchdb-deb/ ${VERSION_CODENAME} main" | \ + tee /etc/apt/sources.list.d/couchdb.list >/dev/null + +# https://github.com/apache/couchdb-pkg/blob/master/debian/README.Debian +RUN set -eux; \ + apt-get update; \ + \ + echo "couchdb couchdb/mode select none" | debconf-set-selections; \ +# we DO want recommends this time + DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-downgrades --allow-remove-essential --allow-change-held-packages \ + couchdb="$COUCHDB_VERSION"~bookworm \ + ; \ +# Undo symlinks to /var/log and /var/lib + rmdir /var/lib/couchdb /var/log/couchdb; \ + rm /opt/couchdb/data /opt/couchdb/var/log; \ + mkdir -p /opt/couchdb/data /opt/couchdb/var/log; \ + chown couchdb:couchdb /opt/couchdb/data /opt/couchdb/var/log; \ + chmod 777 /opt/couchdb/data /opt/couchdb/var/log; \ +# Remove file that sets logging to a file + rm /opt/couchdb/etc/default.d/10-filelog.ini; \ +# Check we own everything in /opt/couchdb. Matches the command in dockerfile_entrypoint.sh + find /opt/couchdb \! \( -user couchdb -group couchdb \) -exec chown -f couchdb:couchdb '{}' +; \ +# Setup directories and permissions for config. Technically these could be 555 and 444 respectively +# but we keep them as 755 and 644 for consistency with CouchDB defaults and the dockerfile_entrypoint.sh. + find /opt/couchdb/etc -type d ! -perm 0755 -exec chmod -f 0755 '{}' +; \ + find /opt/couchdb/etc -type f ! -perm 0644 -exec chmod -f 0644 '{}' +; \ +# only local.d needs to be writable for the docker_entrypoint.sh + chmod -f 0777 /opt/couchdb/etc/local.d; \ +# apt clean-up + rm -rf /var/lib/apt/lists/*; + +# Add configuration +COPY --chown=couchdb:couchdb couch/10-docker-default.ini /opt/couchdb/etc/default.d/ +# COPY --chown=couchdb:couchdb vm.args /opt/couchdb/etc/ + +COPY docker-entrypoint.sh /usr/local/bin +RUN ln -s usr/local/bin/docker-entrypoint.sh /docker-entrypoint.sh # backwards compat +ENTRYPOINT ["tini", "--", "/docker-entrypoint.sh"] + +VOLUME /opt/couchdb/data + +# 5984: Main CouchDB endpoint +# 4369: Erlang portmap daemon (epmd) +# 9100: CouchDB cluster communication port +EXPOSE 5984 4369 9100 +CMD ["/opt/couchdb/bin/couchdb"] + +FROM base as runner ENV COUCHDB_USER admin ENV COUCHDB_PASSWORD admin @@ -6,9 +103,9 @@ EXPOSE 5984 RUN apt-get update && apt-get install -y --no-install-recommends software-properties-common wget unzip curl && \ wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public | apt-key add - && \ - apt-add-repository 'deb http://security.debian.org/debian-security bullseye-security/updates main' && \ + apt-add-repository 'deb http://security.debian.org/debian-security bookworm-security/updates main' && \ apt-add-repository 'deb http://archive.debian.org/debian stretch-backports main' && \ - apt-add-repository 'deb https://packages.adoptium.net/artifactory/deb bullseye main' && \ + apt-add-repository 'deb https://packages.adoptium.net/artifactory/deb bookworm main' && \ apt-get update && apt-get install -y --no-install-recommends temurin-8-jdk && \ rm -rf /var/lib/apt/lists/ diff --git a/hosting/couchdb/clouseau/clouseau.ini b/hosting/couchdb/clouseau/clouseau.ini index 578a5acafa..014fb854f3 100644 --- a/hosting/couchdb/clouseau/clouseau.ini +++ b/hosting/couchdb/clouseau/clouseau.ini @@ -4,7 +4,7 @@ name=clouseau@127.0.0.1 ; set this to the same distributed Erlang cookie used by the CouchDB nodes -cookie=monster +cookie=COUCHDB_ERLANG_COOKIE ; the path where you would like to store the search index files dir=DATA_DIR/search diff --git a/hosting/couchdb/couch/10-docker-default.ini b/hosting/couchdb/couch/10-docker-default.ini new file mode 100644 index 0000000000..1aa633cbfc --- /dev/null +++ b/hosting/couchdb/couch/10-docker-default.ini @@ -0,0 +1,8 @@ +; CouchDB Configuration Settings + +; Custom settings should be made in this file. They will override settings +; in default.ini, but unlike changes made to default.ini, this file won't be +; overwritten on server upgrade. + +[chttpd] +bind_address = any diff --git a/hosting/couchdb/couch/vm.args b/hosting/couchdb/couch/vm.args index e9e4416863..11845dd6d4 100644 --- a/hosting/couchdb/couch/vm.args +++ b/hosting/couchdb/couch/vm.args @@ -12,7 +12,7 @@ # erlang cookie for clouseau security -name couchdb@127.0.0.1 --setcookie monster +-setcookie COUCHDB_ERLANG_COOKIE # Ensure that the Erlang VM listens on a known port -kernel inet_dist_listen_min 9100 diff --git a/hosting/couchdb/docker-entrypoint.sh b/hosting/couchdb/docker-entrypoint.sh new file mode 100755 index 0000000000..bd709b7b73 --- /dev/null +++ b/hosting/couchdb/docker-entrypoint.sh @@ -0,0 +1,122 @@ +#!/bin/bash +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +set -e + +# first arg is `-something` or `+something` +if [ "${1#-}" != "$1" ] || [ "${1#+}" != "$1" ]; then + set -- /opt/couchdb/bin/couchdb "$@" +fi + +# first arg is the bare word `couchdb` +if [ "$1" = 'couchdb' ]; then + shift + set -- /opt/couchdb/bin/couchdb "$@" +fi + +if [ "$1" = '/opt/couchdb/bin/couchdb' ]; then + # this is where runtime configuration changes will be written. + # we need to explicitly touch it here in case /opt/couchdb/etc has + # been mounted as an external volume, in which case it won't exist. + # If running as the couchdb user (i.e. container starts as root), + # write permissions will be granted below. + touch /opt/couchdb/etc/local.d/docker.ini + + # if user is root, assume running under the couchdb user (default) + # and ensure it is able to access files and directories that may be mounted externally + if [ "$(id -u)" = '0' ]; then + # Check that we own everything in /opt/couchdb and fix if necessary. We also + # add the `-f` flag in all the following invocations because there may be + # cases where some of these ownership and permissions issues are non-fatal + # (e.g. a config file owned by root with o+r is actually fine), and we don't + # to be too aggressive about crashing here ... + find /opt/couchdb \! \( -user couchdb -group couchdb \) -exec chown -f couchdb:couchdb '{}' + + + # Ensure that data files have the correct permissions. We were previously + # preventing any access to these files outside of couchdb:couchdb, but it + # turns out that CouchDB itself does not set such restrictive permissions + # when it creates the files. The approach taken here ensures that the + # contents of the datadir have the same permissions as they had when they + # were initially created. This should minimize any startup delay. + find /opt/couchdb/data -type d ! -perm 0755 -exec chmod -f 0755 '{}' + + find /opt/couchdb/data -type f ! -perm 0644 -exec chmod -f 0644 '{}' + + + # Do the same thing for configuration files and directories. Technically + # CouchDB only needs read access to the configuration files as all online + # changes will be applied to the "docker.ini" file below, but we set 644 + # for the sake of consistency. + find /opt/couchdb/etc -type d ! -perm 0755 -exec chmod -f 0755 '{}' + + find /opt/couchdb/etc -type f ! -perm 0644 -exec chmod -f 0644 '{}' + + fi + + if [ ! -z "$NODENAME" ] && ! grep "couchdb@" /opt/couchdb/etc/vm.args; then + echo "-name couchdb@$NODENAME" >> /opt/couchdb/etc/vm.args + fi + + if [ "$COUCHDB_USER" ] && [ "$COUCHDB_PASSWORD" ]; then + # Create admin only if not already present + if ! grep -Pzoqr "\[admins\]\n$COUCHDB_USER =" /opt/couchdb/etc/local.d/*.ini /opt/couchdb/etc/local.ini; then + printf "\n[admins]\n%s = %s\n" "$COUCHDB_USER" "$COUCHDB_PASSWORD" >> /opt/couchdb/etc/local.d/docker.ini + fi + fi + + if [ "$COUCHDB_SECRET" ]; then + # Set secret only if not already present + if ! grep -Pzoqr "\[chttpd_auth\]\nsecret =" /opt/couchdb/etc/local.d/*.ini /opt/couchdb/etc/local.ini; then + printf "\n[chttpd_auth]\nsecret = %s\n" "$COUCHDB_SECRET" >> /opt/couchdb/etc/local.d/docker.ini + fi + fi + + if [ "$COUCHDB_ERLANG_COOKIE" ]; then + cookieFile='/opt/couchdb/.erlang.cookie' + if [ -e "$cookieFile" ]; then + if [ "$(cat "$cookieFile" 2>/dev/null)" != "$COUCHDB_ERLANG_COOKIE" ]; then + echo >&2 + echo >&2 "warning: $cookieFile contents do not match COUCHDB_ERLANG_COOKIE" + echo >&2 + fi + else + echo "$COUCHDB_ERLANG_COOKIE" > "$cookieFile" + fi + chown couchdb:couchdb "$cookieFile" + chmod 600 "$cookieFile" + fi + + if [ "$(id -u)" = '0' ]; then + chown -f couchdb:couchdb /opt/couchdb/etc/local.d/docker.ini || true + fi + + # if we don't find an [admins] section followed by a non-comment, display a warning + if ! grep -Pzoqr '\[admins\]\n[^;]\w+' /opt/couchdb/etc/default.d/*.ini /opt/couchdb/etc/local.d/*.ini /opt/couchdb/etc/local.ini; then + # The - option suppresses leading tabs but *not* spaces. :) + cat >&2 <<-'EOWARN' +************************************************************* +ERROR: CouchDB 3.0+ will no longer run in "Admin Party" + mode. You *MUST* specify an admin user and + password, either via your own .ini file mapped + into the container at /opt/couchdb/etc/local.ini + or inside /opt/couchdb/etc/local.d, or with + "-e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password" + to set it via "docker run". +************************************************************* +EOWARN + exit 1 + fi + + if [ "$(id -u)" = '0' ]; then + export HOME=$(echo ~couchdb) + exec setpriv --reuid=couchdb --regid=couchdb --clear-groups "$@" + fi +fi + +exec "$@" \ No newline at end of file diff --git a/hosting/couchdb/runner.sh b/hosting/couchdb/runner.sh index 9f6a853ca7..aaadee6b43 100644 --- a/hosting/couchdb/runner.sh +++ b/hosting/couchdb/runner.sh @@ -1,6 +1,7 @@ #!/bin/bash DATA_DIR=${DATA_DIR:-/data} +COUCHDB_ERLANG_COOKIE=${COUCHDB_ERLANG_COOKIE:-B9CFC32C-3458-4A86-8448-B3C753991CA7} mkdir -p ${DATA_DIR} mkdir -p ${DATA_DIR}/couch/{dbs,views} @@ -60,6 +61,9 @@ else sed -i "s#DATA_DIR#/data#g" /opt/couchdb/etc/local.ini fi +sed -i "s#COUCHDB_ERLANG_COOKIE#${COUCHDB_ERLANG_COOKIE}#g" /opt/couchdb/etc/vm.args +sed -i "s#COUCHDB_ERLANG_COOKIE#${COUCHDB_ERLANG_COOKIE}#g" /opt/clouseau/clouseau.ini + # Start Clouseau. Budibase won't function correctly without Clouseau running, it # powers the search API endpoints which are used to do all sorts, including # populating app grids. diff --git a/hosting/docker-compose.yaml b/hosting/docker-compose.yaml index 36b88466fe..a72b36aef1 100644 --- a/hosting/docker-compose.yaml +++ b/hosting/docker-compose.yaml @@ -98,7 +98,6 @@ services: couchdb-service: restart: unless-stopped image: budibase/couchdb - pull_policy: always environment: - COUCHDB_PASSWORD=${COUCH_DB_PASSWORD} - COUCHDB_USER=${COUCH_DB_USER} diff --git a/hosting/single/Dockerfile b/hosting/single/Dockerfile index f9044cd124..ee98b0729d 100644 --- a/hosting/single/Dockerfile +++ b/hosting/single/Dockerfile @@ -3,7 +3,6 @@ FROM node:20-slim as build # install node-gyp dependencies RUN apt-get update && apt-get install -y --no-install-recommends g++ make python3 jq - # copy and install dependencies WORKDIR /app COPY package.json . @@ -39,10 +38,9 @@ COPY packages/worker/pm2.config.js packages/worker/pm2.config.js COPY packages/string-templates packages/string-templates -FROM budibase/couchdb as runner +FROM budibase/couchdb:v3.3.3 as runner ARG TARGETARCH ENV TARGETARCH $TARGETARCH -ENV NODE_MAJOR 20 #TARGETBUILD can be set to single (for single docker image) or aas (for azure app service) # e.g. docker build --build-arg TARGETBUILD=aas .... ARG TARGETBUILD=single @@ -60,10 +58,8 @@ RUN apt install -y software-properties-common apt-transport-https ca-certificate && apt install postgresql-client-15 -y \ && apt remove software-properties-common apt-transport-https gpg -y -# install other dependencies, nodejs, oracle requirements, jdk8, redis, nginx -WORKDIR /nodejs -COPY scripts/install-node.sh ./install.sh -RUN chmod +x install.sh && ./install.sh +# We use pm2 in order to run multiple node processes in a single container +RUN npm install --global pm2 # setup nginx COPY hosting/single/nginx/nginx.conf /etc/nginx diff --git a/hosting/single/runner.sh b/hosting/single/runner.sh index 886da4c916..3126eedfb1 100644 --- a/hosting/single/runner.sh +++ b/hosting/single/runner.sh @@ -97,10 +97,12 @@ fi sleep 10 pushd app -pm2 start -l /dev/stdout --name app "yarn run:docker" +pm2 start --name app "yarn run:docker" popd pushd worker -pm2 start -l /dev/stdout --name worker "yarn run:docker" +pm2 start --name worker "yarn run:docker" popd echo "end of runner.sh, sleeping ..." + +tail -f $HOME/.pm2/logs/*.log sleep infinity diff --git a/i18n/README.kr.md b/i18n/README.kr.md new file mode 100644 index 0000000000..09fc83569b --- /dev/null +++ b/i18n/README.kr.md @@ -0,0 +1,221 @@ +

+ + Budibase + +

+

+ Budibase +

+

+ 자체 인프라에서 몇 분 만에 맞춤형 비즈니스 도구를 구축하세요. +

+

+ Budibase는 개발자와 IT 전문가가 몇 분 만에 맞춤형 애플리케이션을 구축하고 자동화할 수 있는 오픈 소스 로우코드 플랫폼입니다. +

+ +

+ 🤖 🎨 🚀 +

+ +

+ Budibase design ui +

+ +

+ + GitHub all releases + + + GitHub release (latest by date) + + + Follow @budibase + + Code of conduct + + + +

+ +

+ 소개 + · + 문서 + · + 기능 요청 + · + 버그 보고 + · + 지원: 토론 +

+ +

+## ✨ 특징 + +### "실제" 소프트웨어를 구축할 수 있습니다. +Budibase를 사용하면 고성능 단일 페이지 애플리케이션을 구축할 수 있습니다. 또한 반응형 디자인으로 제작하여 사용자에게 멋진 경험을 제공할 수 있습니다. +

+ +### 오픈 소스 및 확장성 +Budibase는 오픈소스이며, GPL v3 라이선스에 따라 공개되어 있습니다. 이는 Budibase가 항상 당신 곁에 있다는 안도감을 줄 것입니다. 그리고 우리는 개발자 친화적인 환경을 제공하고 있기 때문에, 당신은 원하는 만큼 소스 코드를 포크하여 수정하거나 Budibase에 직접 기여할 수 있습니다. +

+ +### 기존 데이터 또는 처음부터 시작 +Budibase를 사용하면 다음과 같은 여러 소스에서 데이터를 가져올 수 있습니다: MondoDB, CouchDB, PostgreSQL, MySQL, Airtable, S3, DynamoDB 또는 REST API. + +또는 원하는 경우 외부 도구 없이도 Budibase를 사용하여 처음부터 시작하여 자체 애플리케이션을 구축할 수 있습니다.[데이터 소스 제안](https://github.com/Budibase/budibase/discussions?discussions_q=category%3AIdeas). + +

+ Budibase data +

+

+ +### 강력한 내장 구성 요소로 애플리케이션을 설계하고 구축할 수 있습니다. + +Budibase에는 아름답게 디자인된 강력한 컴포넌트들이 제공되며, 이를 사용하여 UI를 쉽게 구축할 수 있습니다. 또한, CSS를 통한 스타일링 옵션도 풍부하게 제공되어 보다 창의적인 표현도 가능하다. + [Request new component](https://github.com/Budibase/budibase/discussions?discussions_q=category%3AIdeas). + +

+ Budibase design +

+

+ +### 프로세스를 자동화하고, 다른 도구와 연동하고, 웹훅으로 연결하세요! +워크플로우와 수동 프로세스를 자동화하여 시간을 절약하세요. 웹훅 이벤트 연결부터 이메일 자동화까지, Budibase에 수행할 작업을 지시하기만 하면 자동으로 처리됩니다. [새로운 자동화 만들기](https://github.com/Budibase/automations)또는[새로운 자동화를 요청할 수 있습니다](https://github.com/Budibase/budibase/discussions?discussions_q=category%3AIdeas). + +

+ Budibase automations +

+

+ +### 선호하는 도구 +Budibase는 사용자의 선호도에 따라 애플리케이션을 구축할 수 있는 다양한 도구를 통합하고 있습니다. + +

+ Budibase integrations +

+

+ +### 관리자의 천국 +Budibase는 어떤 규모의 프로젝트에도 유연하게 대응할 수 있으며, Budibase를 사용하면 개인 또는 조직의 서버에서 자체 호스팅하고 사용자, 온보딩, SMTP, 앱, 그룹, 테마 등을 한꺼번에 관리할 수 있습니다. 또한, 사용자나 그룹에 앱 포털을 제공하고 그룹 관리자에게 사용자 관리를 맡길 수도 있다. +- 프로모션 비디오: https://youtu.be/xoljVpty_Kw + +


+ +## 🏁 시작 + +Docker, Kubernetes 또는 Digital Ocean을 사용하여 자체 인프라에서 Budibase를 호스팅하거나, 걱정 없이 빠르게 애플리케이션을 구축하려는 경우 클라우드에서 Budibase를 사용할 수 있습니다. + +### [Budibase 셀프 호스팅으로 시작하기](https://docs.budibase.com/docs/hosting-methods) + +- [Docker - single ARM compatible image](https://docs.budibase.com/docs/docker) +- [Docker Compose](https://docs.budibase.com/docs/docker-compose) +- [Kubernetes](https://docs.budibase.com/docs/kubernetes-k8s) +- [Digital Ocean](https://docs.budibase.com/docs/digitalocean) +- [Portainer](https://docs.budibase.com/docs/portainer) + + +### [클라우드에서 Budibase 시작하기](https://budibase.com) + +

+ +## 🎓 Budibase 알아보기 + +문서 [documentacion de Budibase](https://docs.budibase.com/docs). +
+ + +

+ +## 💬 커뮤니티 + +질문하고, 다른 사람을 돕고, 다른 Budibase 사용자와 즐거운 대화를 나눌 수 있는 Budibase 커뮤니티에 여러분을 초대합니다. +[깃허브 토론](https://github.com/Budibase/budibase/discussions) +


+ + +## ❗ 행동강령 + +Budibase 는 모든 계층의 사람들을 환영하고 상호 존중하는 환경을 제공하는 데 특별한 주의를 기울이고 있습니다. 저희는 커뮤니티에도 같은 기대를 가지고 있습니다. +[**행동 강령**](https://github.com/Budibase/budibase/blob/HEAD/.github/CODE_OF_CONDUCT.md). +
+ +

+ + +## 🙌 Contribuir en Budibase + +버그 신고부터 코드의 버그 수정에 이르기까지 모든 기여를 감사하고 환영합니다. 새로운 기능을 구현하거나 API를 변경할 계획이 있다면 [여기에 새 메시지](https://github.com/Budibase/budibase/issues), +이렇게 하면 여러분의 노력이 헛되지 않도록 보장할 수 있습니다. + +여기에는 다음을 위해 Budibase 환경을 설정하는 방법에 대한 지침이 나와 있습니다. [여기를 클릭하세요](https://github.com/Budibase/budibase/tree/HEAD/docs/CONTRIBUTING.md). + +### 어디서부터 시작해야 할지 혼란스러우신가요? +이곳은 기여를 시작하기에 최적의 장소입니다! [First time issues project](https://github.com/Budibase/budibase/projects/22). + +### 리포지토리 구성 + +Budibase는 Lerna에서 관리하는 단일 리포지토리입니다. Lerna는 변경 사항이 있을 때마다 이를 동기화하여 Budibase 패키지를 빌드하고 게시합니다. 크게 보면 이러한 패키지가 Budibase를 구성하는 패키지입니다: + +- [packages/builder](https://github.com/Budibase/budibase/tree/HEAD/packages/builder) - budibase builder 클라이언트 측의 svelte 애플리케이션 코드가 포함되어 있습니다. + +- [packages/client](https://github.com/Budibase/budibase/tree/HEAD/packages/client) - budibase builder 클라이언트 측의 svelte 애플리케이션 코드가 포함되어 있습니다. + +- [packages/server](https://github.com/Budibase/budibase/tree/HEAD/packages/server) - Budibase의 서버 부분입니다. 이 Koa 애플리케이션은 빌더에게 Budibase 애플리케이션을 생성하는 데 필요한 것을 제공하는 역할을 합니다. 또한 데이터베이스 및 파일 저장소와 상호 작용할 수 있는 API를 제공합니다. + +자세한 내용은 다음 문서를 참조하세요. [CONTRIBUTING.md](https://github.com/Budibase/budibase/blob/HEAD/docs/CONTRIBUTING.md) + +

+ + +## 📝 라이선스 + +Budibase는 오픈 소스이며, 라이선스는 다음과 같습니다 [GPL v3](https://www.gnu.org/licenses/gpl-3.0.en.html). 클라이언트 및 컴포넌트 라이브러리는 다음과 같이 라이선스가 부여됩니다. [MPL](https://directory.fsf.org/wiki/License:MPL-2.0) - 이렇게 하면 빌드한 애플리케이션에 원하는 대로 라이선스를 부여할 수 있습니다. + +

+ +## ⭐ 스타 수의 역사 + +[![Stargazers over time](https://starchart.cc/Budibase/budibase.svg)](https://starchart.cc/Budibase/budibase) + +빌더 업데이트 중 문제가 발생하는 경우 [여기](https://github.com/Budibase/budibase/blob/HEAD/docs/CONTRIBUTING.md#troubleshooting) 를 참고하여 환경을 정리해 주세요. + +

+ +## Contributors ✨ + +훌륭한 여러분께 감사할 따름입니다. ([emoji key](https://allcontributors.org/docs/en/emoji-key)): + + + + + + + + + + + + + + + + + + + + + + + + + +

Martin McKeaveney

💻 📖 ⚠️ 🚇

Michael Drury

📖 💻 ⚠️ 🚇

Andrew Kingston

📖 💻 ⚠️ 🎨

Michael Shanks

📖 💻 ⚠️

Kevin Åberg Kultalahti

📖 💻 ⚠️

Joe

📖 💻 🖋 🎨

Rory Powell

💻 📖 ⚠️

Peter Clement

💻 📖 ⚠️

Conor_Mack

💻 ⚠️

pngwn

💻 ⚠️

HugoLd

💻

victoriasloan

💻

yashank09

💻

SOVLOOKUP

💻

seoulaja

🌍

Maurits Lourens

⚠️ 💻
+ + + + + + +이 프로젝트는 다음 사양을 따릅니다. [all-contributors](https://github.com/all-contributors/all-contributors). +모든 종류의 기여를 환영합니다! diff --git a/lerna.json b/lerna.json index 4940336b29..4807a80646 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.19.4", + "version": "2.20.14", "npmClient": "yarn", "packages": [ "packages/*", diff --git a/package.json b/package.json index 4407fd33f3..0a20f01d52 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "nx-cloud": "16.0.5", "prettier": "2.8.8", "prettier-plugin-svelte": "^2.3.0", - "svelte": "3.49.0", + "svelte": "^4.2.10", "svelte-eslint-parser": "^0.33.1", "typescript": "5.2.2", "yargs": "^17.7.2" diff --git a/packages/backend-core/src/db/couch/DatabaseImpl.ts b/packages/backend-core/src/db/couch/DatabaseImpl.ts index 0e2b4173b0..7e7c997cbe 100644 --- a/packages/backend-core/src/db/couch/DatabaseImpl.ts +++ b/packages/backend-core/src/db/couch/DatabaseImpl.ts @@ -11,6 +11,7 @@ import { Document, isDocument, RowResponse, + RowValue, } from "@budibase/types" import { getCouchInfo } from "./connections" import { directCouchUrlCall } from "./utils" @@ -221,7 +222,7 @@ export class DatabaseImpl implements Database { }) } - async allDocs( + async allDocs( params: DatabaseQueryOpts ): Promise> { return this.performCall(db => { diff --git a/packages/backend-core/src/db/instrumentation.ts b/packages/backend-core/src/db/instrumentation.ts index aa2ac424ae..03010d4c92 100644 --- a/packages/backend-core/src/db/instrumentation.ts +++ b/packages/backend-core/src/db/instrumentation.ts @@ -1,5 +1,4 @@ import { - DocumentScope, DocumentDestroyResponse, DocumentInsertResponse, DocumentBulkResponse, @@ -13,6 +12,7 @@ import { DatabasePutOpts, DatabaseQueryOpts, Document, + RowValue, } from "@budibase/types" import tracer from "dd-trace" import { Writable } from "stream" @@ -79,7 +79,7 @@ export class DDInstrumentedDatabase implements Database { }) } - allDocs( + allDocs( params: DatabaseQueryOpts ): Promise> { return tracer.trace("db.allDocs", span => { diff --git a/packages/backend-core/src/docIds/ids.ts b/packages/backend-core/src/docIds/ids.ts index 02176109da..9627b2b94c 100644 --- a/packages/backend-core/src/docIds/ids.ts +++ b/packages/backend-core/src/docIds/ids.ts @@ -74,7 +74,7 @@ export function getGlobalIDFromUserMetadataID(id: string) { * Generates a template ID. * @param ownerId The owner/user of the template, this could be global or a workspace level. */ -export function generateTemplateID(ownerId: any) { +export function generateTemplateID(ownerId: string) { return `${DocumentType.TEMPLATE}${SEPARATOR}${ownerId}${SEPARATOR}${newid()}` } @@ -105,7 +105,7 @@ export function prefixRoleID(name: string) { * Generates a new dev info document ID - this is scoped to a user. * @returns The new dev info ID which info for dev (like api key) can be stored under. */ -export const generateDevInfoID = (userId: any) => { +export const generateDevInfoID = (userId: string) => { return `${DocumentType.DEV_INFO}${SEPARATOR}${userId}` } diff --git a/packages/backend-core/src/events/publishers/query.ts b/packages/backend-core/src/events/publishers/query.ts index 7d28129cf6..48603257d2 100644 --- a/packages/backend-core/src/events/publishers/query.ts +++ b/packages/backend-core/src/events/publishers/query.ts @@ -3,6 +3,7 @@ import { Event, Datasource, Query, + QueryPreview, QueryCreatedEvent, QueryUpdatedEvent, QueryDeletedEvent, @@ -68,9 +69,9 @@ const run = async (count: number, timestamp?: string | number) => { await publishEvent(Event.QUERIES_RUN, properties, timestamp) } -const previewed = async (datasource: Datasource, query: Query) => { +const previewed = async (datasource: Datasource, query: QueryPreview) => { const properties: QueryPreviewedEvent = { - queryId: query._id, + queryId: query.queryId, datasourceId: datasource._id as string, source: datasource.source, queryVerb: query.queryVerb, diff --git a/packages/backend-core/src/installation.ts b/packages/backend-core/src/installation.ts index ca35b926fb..83166880cc 100644 --- a/packages/backend-core/src/installation.ts +++ b/packages/backend-core/src/installation.ts @@ -6,6 +6,7 @@ import * as context from "./context" import semver from "semver" import { bustCache, withCache, TTL, CacheKey } from "./cache/generic" import environment from "./environment" +import { logAlert } from "./logging" export const getInstall = async (): Promise => { return withCache(CacheKey.INSTALLATION, TTL.ONE_DAY, getInstallFromDB, { @@ -80,27 +81,35 @@ export const checkInstallVersion = async (): Promise => { const currentVersion = install.version const newVersion = environment.VERSION - if (currentVersion !== newVersion) { - const isUpgrade = semver.gt(newVersion, currentVersion) - const isDowngrade = semver.lt(newVersion, currentVersion) + try { + if (currentVersion !== newVersion) { + const isUpgrade = semver.gt(newVersion, currentVersion) + const isDowngrade = semver.lt(newVersion, currentVersion) - const success = await updateVersion(newVersion) + const success = await updateVersion(newVersion) - if (success) { - await context.doInIdentityContext( - { - _id: install.installId, - type: IdentityType.INSTALLATION, - }, - async () => { - if (isUpgrade) { - await events.installation.upgraded(currentVersion, newVersion) - } else if (isDowngrade) { - await events.installation.downgraded(currentVersion, newVersion) + if (success) { + await context.doInIdentityContext( + { + _id: install.installId, + type: IdentityType.INSTALLATION, + }, + async () => { + if (isUpgrade) { + await events.installation.upgraded(currentVersion, newVersion) + } else if (isDowngrade) { + await events.installation.downgraded(currentVersion, newVersion) + } } - } - ) - await events.identification.identifyInstallationGroup(install.installId) + ) + await events.identification.identifyInstallationGroup(install.installId) + } + } + } catch (err: any) { + if (err?.message?.includes("Invalid Version")) { + logAlert(`Invalid version "${newVersion}" - is it semver?`) + } else { + logAlert("Failed to retrieve version", err) } } } diff --git a/packages/backend-core/src/logging/correlation/correlation.ts b/packages/backend-core/src/logging/correlation/correlation.ts index 0498bd43d5..13cc7aff8f 100644 --- a/packages/backend-core/src/logging/correlation/correlation.ts +++ b/packages/backend-core/src/logging/correlation/correlation.ts @@ -2,11 +2,12 @@ import { Header } from "../../constants" const correlator = require("correlation-id") -export const setHeader = (headers: any) => { +export const setHeader = (headers: Record) => { const correlationId = correlator.getId() - if (correlationId) { - headers[Header.CORRELATION_ID] = correlationId + if (!correlationId) { + return } + headers[Header.CORRELATION_ID] = correlationId } export function getId() { diff --git a/packages/backend-core/src/middleware/joi-validator.ts b/packages/backend-core/src/middleware/joi-validator.ts index fcc8316886..ac8064a512 100644 --- a/packages/backend-core/src/middleware/joi-validator.ts +++ b/packages/backend-core/src/middleware/joi-validator.ts @@ -1,12 +1,12 @@ -import Joi, { ObjectSchema } from "joi" -import { BBContext } from "@budibase/types" +import Joi from "joi" +import { Ctx } from "@budibase/types" function validate( schema: Joi.ObjectSchema | Joi.ArraySchema, property: string ) { // Return a Koa middleware function - return (ctx: BBContext, next: any) => { + return (ctx: Ctx, next: any) => { if (!schema) { return next() } @@ -30,7 +30,6 @@ function validate( const { error } = schema.validate(params) if (error) { ctx.throw(400, `Invalid ${property} - ${error.message}`) - return } return next() } diff --git a/packages/backend-core/src/objectStore/buckets/plugins.ts b/packages/backend-core/src/objectStore/buckets/plugins.ts index 6f1b7116ae..02be9345ab 100644 --- a/packages/backend-core/src/objectStore/buckets/plugins.ts +++ b/packages/backend-core/src/objectStore/buckets/plugins.ts @@ -6,7 +6,7 @@ import { Plugin } from "@budibase/types" // URLS -export function enrichPluginURLs(plugins: Plugin[]) { +export function enrichPluginURLs(plugins?: Plugin[]): Plugin[] { if (!plugins || !plugins.length) { return [] } diff --git a/packages/backend-core/src/redis/utils.ts b/packages/backend-core/src/redis/utils.ts index 4d8b1bb9a4..7b93458b52 100644 --- a/packages/backend-core/src/redis/utils.ts +++ b/packages/backend-core/src/redis/utils.ts @@ -29,6 +29,7 @@ export enum Databases { WRITE_THROUGH = "writeThrough", LOCKS = "locks", SOCKET_IO = "socket_io", + BPM_EVENTS = "bpmEvents", } /** diff --git a/packages/backend-core/tests/core/utilities/mocks/licenses.ts b/packages/backend-core/tests/core/utilities/mocks/licenses.ts index 758fd6bf9a..1cbc282575 100644 --- a/packages/backend-core/tests/core/utilities/mocks/licenses.ts +++ b/packages/backend-core/tests/core/utilities/mocks/licenses.ts @@ -58,7 +58,7 @@ export const useCloudFree = () => { // FEATURES const useFeature = (feature: Feature) => { - const license = cloneDeep(UNLIMITED_LICENSE) + const license = cloneDeep(getCachedLicense() || UNLIMITED_LICENSE) const opts: UseLicenseOpts = { features: [feature], } diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 78eed2b608..a1baa2a38b 100644 --- a/packages/bbui/package.json +++ b/packages/bbui/package.json @@ -24,8 +24,7 @@ "rollup": "^2.45.2", "rollup-plugin-postcss": "^4.0.0", "rollup-plugin-svelte": "^7.1.0", - "rollup-plugin-terser": "^7.0.2", - "svelte": "3.49.0" + "rollup-plugin-terser": "^7.0.2" }, "keywords": [ "svelte" diff --git a/packages/bbui/src/ActionButton/ActionButton.svelte b/packages/bbui/src/ActionButton/ActionButton.svelte index 0e6ec3d155..c346e34d54 100644 --- a/packages/bbui/src/ActionButton/ActionButton.svelte +++ b/packages/bbui/src/ActionButton/ActionButton.svelte @@ -41,6 +41,7 @@ } + (showTooltip = true)} diff --git a/packages/bbui/src/ActionMenu/ActionMenu.svelte b/packages/bbui/src/ActionMenu/ActionMenu.svelte index 08425e8f59..642ec4932a 100644 --- a/packages/bbui/src/ActionMenu/ActionMenu.svelte +++ b/packages/bbui/src/ActionMenu/ActionMenu.svelte @@ -33,6 +33,8 @@ setContext("actionMenu", { show, hide }) + +
diff --git a/packages/bbui/src/Badge/Badge.svelte b/packages/bbui/src/Badge/Badge.svelte index 8b54045297..e4ec7d4f33 100644 --- a/packages/bbui/src/Badge/Badge.svelte +++ b/packages/bbui/src/Badge/Badge.svelte @@ -13,6 +13,8 @@ export let hoverable = false + + + +
+ +
diff --git a/packages/bbui/src/DetailSummary/DetailSummary.svelte b/packages/bbui/src/DetailSummary/DetailSummary.svelte index 2cbb6796f3..cbfdcbec9b 100644 --- a/packages/bbui/src/DetailSummary/DetailSummary.svelte +++ b/packages/bbui/src/DetailSummary/DetailSummary.svelte @@ -15,6 +15,8 @@ } + +
{#if name}
diff --git a/packages/bbui/src/FancyForm/FancyField.svelte b/packages/bbui/src/FancyForm/FancyField.svelte index 455f4b38fb..798f486187 100644 --- a/packages/bbui/src/FancyForm/FancyField.svelte +++ b/packages/bbui/src/FancyForm/FancyField.svelte @@ -36,6 +36,8 @@ }) + +
+
+ +
{/key} {#if open} +
{/if} diff --git a/packages/bbui/src/Form/Core/Dropzone.svelte b/packages/bbui/src/Form/Core/Dropzone.svelte index fa0be630ba..2bd95df516 100644 --- a/packages/bbui/src/Form/Core/Dropzone.svelte +++ b/packages/bbui/src/Form/Core/Dropzone.svelte @@ -137,6 +137,9 @@ } + + +
{#if selectedImage} {#if gallery} diff --git a/packages/bbui/src/Form/Core/EnvDropdown.svelte b/packages/bbui/src/Form/Core/EnvDropdown.svelte index c690ffbc6b..ed5878d6b2 100644 --- a/packages/bbui/src/Form/Core/EnvDropdown.svelte +++ b/packages/bbui/src/Form/Core/EnvDropdown.svelte @@ -96,6 +96,8 @@ } + +
+ +
{#if value}
diff --git a/packages/bbui/src/Form/Core/InputDropdown.svelte b/packages/bbui/src/Form/Core/InputDropdown.svelte index 128353b7b9..c1bc2ac7e5 100644 --- a/packages/bbui/src/Form/Core/InputDropdown.svelte +++ b/packages/bbui/src/Form/Core/InputDropdown.svelte @@ -110,6 +110,7 @@ } +
+ +
+ +
(showTooltip = true)} diff --git a/packages/bbui/src/IconPicker/IconPicker.svelte b/packages/bbui/src/IconPicker/IconPicker.svelte index b3cc72daa3..3cd7a16eb0 100644 --- a/packages/bbui/src/IconPicker/IconPicker.svelte +++ b/packages/bbui/src/IconPicker/IconPicker.svelte @@ -58,6 +58,8 @@ } + +
(open = true)}>
+ +
+ +
copyToClipboard(value)}> diff --git a/packages/bbui/src/Layout/Page.svelte b/packages/bbui/src/Layout/Page.svelte index 57c264231b..2169a12459 100644 --- a/packages/bbui/src/Layout/Page.svelte +++ b/packages/bbui/src/Layout/Page.svelte @@ -43,6 +43,7 @@ flex-direction: row; justify-content: flex-start; align-items: stretch; + overflow-y: scroll !important; flex: 1 1 auto; overflow-x: hidden; } diff --git a/packages/bbui/src/List/ListItem.svelte b/packages/bbui/src/List/ListItem.svelte index 28015c4c57..76b242cf9c 100644 --- a/packages/bbui/src/List/ListItem.svelte +++ b/packages/bbui/src/List/ListItem.svelte @@ -15,6 +15,8 @@ $: initials = avatar ? title?.[0] : null + +
{#if icon} diff --git a/packages/bbui/src/Menu/Item.svelte b/packages/bbui/src/Menu/Item.svelte index ed759f5b10..05a33adda9 100644 --- a/packages/bbui/src/Menu/Item.svelte +++ b/packages/bbui/src/Menu/Item.svelte @@ -33,6 +33,7 @@ } +
  • + +
    Click me {remaining} diff --git a/packages/bbui/src/Modal/Modal.svelte b/packages/bbui/src/Modal/Modal.svelte index da97bf332e..f891d0584d 100644 --- a/packages/bbui/src/Modal/Modal.svelte +++ b/packages/bbui/src/Modal/Modal.svelte @@ -100,6 +100,7 @@ --> {#if visible} +
    + +
    + +