Merge branch 'develop' into api-tets-public-api-key-generation
This commit is contained in:
commit
781ff726f0
|
@ -2,10 +2,11 @@
|
|||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
labels: bug, linear
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Checklist**
|
||||
- [ ] I have searched budibase discussions and github issues to check if my issue already exists
|
||||
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
name: Budibase Deploy Preprod
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
INTERCOM_TOKEN: ${{ secrets.INTERCOM_TOKEN }}
|
||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- 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: Get the latest budibase release version
|
||||
id: version
|
||||
run: |
|
||||
release_version=$(cat lerna.json | jq -r '.version')
|
||||
echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
|
||||
|
||||
- name: Pull values.yaml from budibase-infra
|
||||
run: |
|
||||
curl -H "Authorization: token ${{ secrets.GH_PERSONAL_TOKEN }}" \
|
||||
-H 'Accept: application/vnd.github.v3.raw' \
|
||||
-o values.preprod.yaml \
|
||||
-L https://api.github.com/repos/budibase/budibase-infra/contents/kubernetes/budibase-preprod/values.yaml
|
||||
wc -l values.preprod.yaml
|
||||
|
||||
- name: Deploy to Preprod Environment
|
||||
uses: glopezep/helm@v1.7.1
|
||||
with:
|
||||
release: budibase-preprod
|
||||
namespace: budibase
|
||||
chart: charts/budibase
|
||||
token: ${{ github.token }}
|
||||
helm: helm3
|
||||
values: |
|
||||
globals:
|
||||
appVersion: v${{ env.RELEASE_VERSION }}
|
||||
ingress:
|
||||
enabled: true
|
||||
nginx: true
|
||||
value-files: >-
|
||||
[
|
||||
"values.preprod.yaml"
|
||||
]
|
||||
env:
|
||||
KUBECONFIG_FILE: '${{ secrets.PREPROD_KUBECONFIG }}'
|
||||
|
||||
- name: Discord Webhook Action
|
||||
uses: tsickert/discord-webhook@v4.0.0
|
||||
with:
|
||||
webhook-url: ${{ secrets.PROD_DEPLOY_WEBHOOK_URL }}
|
||||
content: "Preprod Deployment Complete: ${{ env.RELEASE_VERSION }} deployed to Budibase Pre-prod."
|
||||
embed-title: ${{ env.RELEASE_VERSION }}
|
|
@ -1,88 +0,0 @@
|
|||
name: Budibase Deploy Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- 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: Fail if branch is not develop
|
||||
if: github.ref != 'refs/heads/develop'
|
||||
run: |
|
||||
echo "Ref is not develop, you must run this job from develop."
|
||||
exit 1
|
||||
|
||||
- name: Get the latest budibase release version
|
||||
id: version
|
||||
run: |
|
||||
release_version=$(cat lerna.json | jq -r '.version')
|
||||
echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
|
||||
|
||||
- name: Pull values.yaml from budibase-infra
|
||||
run: |
|
||||
curl -H "Authorization: token ${{ secrets.GH_PERSONAL_TOKEN }}" \
|
||||
-H 'Accept: application/vnd.github.v3.raw' \
|
||||
-o values.release.yaml \
|
||||
-L https://api.github.com/repos/budibase/budibase-infra/contents/kubernetes/budibase-release/values.yaml
|
||||
wc -l values.release.yaml
|
||||
|
||||
- name: Deploy to Release Environment
|
||||
uses: glopezep/helm@v1.7.1
|
||||
with:
|
||||
release: budibase-release
|
||||
namespace: budibase
|
||||
chart: charts/budibase
|
||||
token: ${{ github.token }}
|
||||
helm: helm3
|
||||
values: |
|
||||
globals:
|
||||
appVersion: develop
|
||||
ingress:
|
||||
enabled: true
|
||||
nginx: true
|
||||
value-files: >-
|
||||
[
|
||||
"values.release.yaml"
|
||||
]
|
||||
env:
|
||||
KUBECONFIG_FILE: '${{ secrets.RELEASE_KUBECONFIG }}'
|
||||
|
||||
- name: Re roll app-service
|
||||
uses: actions-hub/kubectl@master
|
||||
env:
|
||||
KUBE_CONFIG: ${{ secrets.RELEASE_KUBECONFIG_BASE64 }}
|
||||
with:
|
||||
args: rollout restart deployment app-service -n budibase
|
||||
|
||||
- name: Re roll proxy-service
|
||||
uses: actions-hub/kubectl@master
|
||||
env:
|
||||
KUBE_CONFIG: ${{ secrets.RELEASE_KUBECONFIG_BASE64 }}
|
||||
with:
|
||||
args: rollout restart deployment proxy-service -n budibase
|
||||
|
||||
- name: Re roll worker-service
|
||||
uses: actions-hub/kubectl@master
|
||||
env:
|
||||
KUBE_CONFIG: ${{ secrets.RELEASE_KUBECONFIG_BASE64 }}
|
||||
with:
|
||||
args: rollout restart deployment worker-service -n budibase
|
||||
|
||||
|
||||
- name: Discord Webhook Action
|
||||
uses: tsickert/discord-webhook@v4.0.0
|
||||
with:
|
||||
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 }}
|
|
@ -117,4 +117,4 @@ jobs:
|
|||
with:
|
||||
repository: budibase/budibase-deploys
|
||||
event: budicloud-qa-deploy
|
||||
github_pat: ${{ secrets.GH_ACCESS_TOKEN }}
|
||||
github_pat: ${{ secrets.GH_ACCESS_TOKEN }}
|
||||
|
|
|
@ -35,9 +35,8 @@ env:
|
|||
PERSONAL_ACCESS_TOKEN : ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
||||
|
||||
jobs:
|
||||
release:
|
||||
release-images:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Fail if branch is not master
|
||||
if: github.ref != 'refs/heads/master'
|
||||
|
@ -57,14 +56,6 @@ jobs:
|
|||
- 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:
|
||||
|
@ -90,46 +81,59 @@ jobs:
|
|||
DOCKER_USER: ${{ secrets.DOCKER_USERNAME }}
|
||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_API_KEY }}
|
||||
BUDIBASE_RELEASE_VERSION: ${{ steps.previoustag.outputs.tag }}
|
||||
|
||||
- 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: |
|
||||
curl -H "Authorization: token ${{ secrets.GH_PERSONAL_TOKEN }}" \
|
||||
-H 'Accept: application/vnd.github.v3.raw' \
|
||||
-o values.preprod.yaml \
|
||||
-L https://api.github.com/repos/budibase/budibase-infra/contents/kubernetes/budibase-preprod/values.yaml
|
||||
wc -l values.preprod.yaml
|
||||
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
|
||||
|
||||
- name: Deploy to Preprod Environment
|
||||
uses: glopezep/helm@v1.7.1
|
||||
with:
|
||||
release: budibase-preprod
|
||||
namespace: budibase
|
||||
chart: charts/budibase
|
||||
token: ${{ github.token }}
|
||||
helm: helm3
|
||||
values: |
|
||||
globals:
|
||||
appVersion: ${{ steps.previoustag.outputs.tag }}
|
||||
ingress:
|
||||
enabled: true
|
||||
nginx: true
|
||||
value-files: >-
|
||||
[
|
||||
"values.preprod.yaml"
|
||||
]
|
||||
- name: 'Get Previous tag'
|
||||
id: previoustag
|
||||
uses: "WyriHaximus/github-action-get-previous-tag@v1"
|
||||
|
||||
# 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-master --app-version "$RELEASE_VERSION" --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: ${{ env.RELEASE_VERSION }}"
|
||||
git push
|
||||
env:
|
||||
KUBECONFIG_FILE: '${{ secrets.PREPROD_KUBECONFIG }}'
|
||||
RELEASE_VERSION: ${{ steps.previoustag.outputs.tag }}
|
||||
|
||||
- name: Discord Webhook Action
|
||||
uses: tsickert/discord-webhook@v4.0.0
|
||||
|
||||
# Trigger deploy to new EKS preprod environment
|
||||
trigger-deploy-to-preprod-env:
|
||||
needs: [release-helm-chart]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: 'Get Previous tag'
|
||||
id: previoustag
|
||||
uses: "WyriHaximus/github-action-get-previous-tag@v1"
|
||||
|
||||
- uses: passeidireto/trigger-external-workflow-action@main
|
||||
env:
|
||||
PAYLOAD_VERSION: ${{ steps.previoustag.outputs.tag }}
|
||||
with:
|
||||
webhook-url: ${{ secrets.PROD_DEPLOY_WEBHOOK_URL }}
|
||||
content: "Preprod Deployment Complete: ${{ steps.previoustag.outputs.tag }} deployed to Budibase Pre-prod."
|
||||
embed-title: ${{ steps.previoustag.outputs.tag }}
|
||||
repository: budibase/budibase-deploys
|
||||
event: budicloud-preprod-deploy
|
||||
github_pat: ${{ secrets.GH_ACCESS_TOKEN }}
|
|
@ -16,9 +16,13 @@ jobs:
|
|||
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
node-version: 14.x
|
||||
fetch_depth: 0
|
||||
|
||||
- name: Use Node.js 14.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 14.x
|
||||
|
||||
- name: Get the latest budibase release version
|
||||
id: version
|
||||
run: |
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
name: Budibase Nightly Tests
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 5 * * *" # every day at 5AM
|
||||
|
||||
jobs:
|
||||
nightly:
|
||||
runs-on: [self-hosted, qa]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js 14.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 14.x
|
||||
- name: QA Core Integration Tests
|
||||
run: |
|
||||
cd qa-core
|
||||
yarn
|
||||
yarn api:test:ci
|
||||
env:
|
||||
BUDIBASE_HOST: budicloud.qa.budibase.net
|
||||
BUDIBASE_ACCOUNTS_URL: https://account-portal.budicloud.qa.budibase.net
|
||||
|
||||
- name: Cypress Discord Notify
|
||||
run: yarn test:notify
|
||||
env:
|
||||
WEBHOOK_URL: ${{ secrets.BUDI_QA_WEBHOOK }}
|
||||
GITHUB_RUN_URL: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID
|
|
@ -51,6 +51,14 @@ spec:
|
|||
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 }}
|
||||
{{ if .Values.services.proxy.proxyRateLimitWebhooksPerSecond }}
|
||||
- name: PROXY_RATE_LIMIT_WEBHOOKS_PER_SECOND
|
||||
value: {{ .Values.services.proxy.proxyRateLimitWebhooksPerSecond | quote }}
|
||||
{{ end }}
|
||||
{{ if .Values.services.proxy.proxyRateLimitApiPerSecond }}
|
||||
- name: PROXY_RATE_LIMIT_API_PER_SECOND
|
||||
value: {{ .Values.services.proxy.proxyRateLimitApiPerSecond | quote }}
|
||||
{{ end }}
|
||||
- name: RESOLVER
|
||||
{{ if .Values.services.proxy.resolver }}
|
||||
value: {{ .Values.services.proxy.resolver }}
|
||||
|
|
|
@ -245,7 +245,7 @@ couchdb:
|
|||
## The CouchDB image
|
||||
image:
|
||||
repository: couchdb
|
||||
tag: 3.2.1
|
||||
tag: 3.1.1
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
## Experimental integration with Lucene-powered fulltext search
|
||||
|
|
|
@ -52,4 +52,14 @@ So this command will actually run the application in dev mode. It creates .env f
|
|||
|
||||
The dev version will be available on port 10000 i.e.
|
||||
|
||||
http://127.0.0.1:10000/builder/admin
|
||||
http://127.0.0.1:10000/builder/admin
|
||||
|
||||
### File descriptor issues with Vite and Chrome in Linux
|
||||
If your dev environment stalls forever, with some network requests stuck in flight, it's likely that Chrome is trying to open more file descriptors than your system allows.
|
||||
To fix this, apply the following tweaks.
|
||||
|
||||
Debian based distros:
|
||||
Add `* - nofile 65536` to `/etc/security/limits.conf`.
|
||||
|
||||
Arch:
|
||||
Add `DefaultLimitNOFILE=65536` to `/etc/systemd/system.conf`.
|
|
@ -6,8 +6,7 @@ services:
|
|||
minio-service:
|
||||
container_name: budi-minio-dev
|
||||
restart: on-failure
|
||||
# Last version that supports the "fs" backend
|
||||
image: minio/minio:RELEASE.2022-10-24T18-35-07Z
|
||||
image: minio/minio
|
||||
volumes:
|
||||
- minio_data:/data
|
||||
ports:
|
||||
|
@ -69,4 +68,4 @@ volumes:
|
|||
minio_data:
|
||||
driver: local
|
||||
redis_data:
|
||||
driver: local
|
||||
driver: local
|
||||
|
|
|
@ -55,12 +55,12 @@ http {
|
|||
set $csp_style "style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://fonts.googleapis.com https://rsms.me https://maxcdn.bootstrapcdn.com";
|
||||
set $csp_object "object-src 'none'";
|
||||
set $csp_base_uri "base-uri 'self'";
|
||||
set $csp_connect "connect-src 'self' https://*.budibase.net https://api-iam.intercom.io https://api-iam.intercom.io https://api-ping.intercom.io https://app.posthog.com wss://nexus-websocket-a.intercom.io wss://nexus-websocket-b.intercom.io https://nexus-websocket-a.intercom.io https://nexus-websocket-b.intercom.io https://uploads.intercomcdn.com https://uploads.intercomusercontent.com https://*.s3.*.amazonaws.com https://s3.*.amazonaws.com https://api.github.com";
|
||||
set $csp_connect "connect-src 'self' https://*.budibase.net https://api-iam.intercom.io https://api-iam.intercom.io https://api-ping.intercom.io https://app.posthog.com wss://nexus-websocket-a.intercom.io wss://nexus-websocket-b.intercom.io https://nexus-websocket-a.intercom.io https://nexus-websocket-b.intercom.io https://uploads.intercomcdn.com https://uploads.intercomusercontent.com https://*.s3.amazonaws.com https://*.s3.us-east-2.amazonaws.com https://*.s3.us-east-1.amazonaws.com https://*.s3.us-west-1.amazonaws.com https://*.s3.us-west-2.amazonaws.com https://*.s3.af-south-1.amazonaws.com https://*.s3.ap-east-1.amazonaws.com https://*.s3.ap-southeast-3.amazonaws.com https://*.s3.ap-south-1.amazonaws.com https://*.s3.ap-northeast-3.amazonaws.com https://*.s3.ap-northeast-2.amazonaws.com https://*.s3.ap-southeast-1.amazonaws.com https://*.s3.ap-southeast-2.amazonaws.com https://*.s3.ap-northeast-1.amazonaws.com https://*.s3.ca-central-1.amazonaws.com https://*.s3.cn-north-1.amazonaws.com https://*.s3.cn-northwest-1.amazonaws.com https://*.s3.eu-central-1.amazonaws.com https://*.s3.eu-west-1.amazonaws.com https://*.s3.eu-west-2.amazonaws.com https://*.s3.eu-south-1.amazonaws.com https://*.s3.eu-west-3.amazonaws.com https://*.s3.eu-north-1.amazonaws.com https://*.s3.sa-east-1.amazonaws.com https://*.s3.me-south-1.amazonaws.com https://*.s3.us-gov-east-1.amazonaws.com https://*.s3.us-gov-west-1.amazonaws.com https://api.github.com";
|
||||
set $csp_font "font-src 'self' data: https://cdn.jsdelivr.net https://fonts.gstatic.com https://rsms.me https://maxcdn.bootstrapcdn.com https://js.intercomcdn.com https://fonts.intercomcdn.com";
|
||||
set $csp_frame "frame-src 'self' https:";
|
||||
set $csp_img "img-src http: https: data: blob:";
|
||||
set $csp_manifest "manifest-src 'self'";
|
||||
set $csp_media "media-src 'self' https://js.intercomcdn.com";
|
||||
set $csp_media "media-src 'self' https://js.intercomcdn.com https://cdn.budi.live";
|
||||
set $csp_worker "worker-src 'none'";
|
||||
|
||||
error_page 502 503 504 /error.html;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": "2.3.18-alpha.29",
|
||||
"version": "2.4.8-alpha.4",
|
||||
"npmClient": "yarn",
|
||||
"packages": [
|
||||
"packages/*"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/backend-core",
|
||||
"version": "2.3.18-alpha.29",
|
||||
"version": "2.4.8-alpha.4",
|
||||
"description": "Budibase backend core libraries used in server and worker",
|
||||
"main": "dist/src/index.js",
|
||||
"types": "dist/src/index.d.ts",
|
||||
|
@ -22,9 +22,9 @@
|
|||
"test:watch": "jest --watchAll"
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/nano": "10.1.1",
|
||||
"@budibase/nano": "10.1.2",
|
||||
"@budibase/pouchdb-replication-stream": "1.2.10",
|
||||
"@budibase/types": "2.3.18-alpha.29",
|
||||
"@budibase/types": "2.4.8-alpha.4",
|
||||
"@shopify/jest-koa-mocks": "5.0.1",
|
||||
"@techpass/passport-openidconnect": "0.3.2",
|
||||
"aws-cloudfront-sign": "2.2.0",
|
||||
|
|
|
@ -28,6 +28,7 @@ import * as events from "../events"
|
|||
import * as configs from "../configs"
|
||||
import { clearCookie, getCookie } from "../utils"
|
||||
import { ssoSaveUserNoOp } from "../middleware/passport/sso/sso"
|
||||
import env from "../environment"
|
||||
|
||||
const refresh = require("passport-oauth2-refresh")
|
||||
export {
|
||||
|
@ -52,7 +53,7 @@ export const jwt = require("jsonwebtoken")
|
|||
_passport.use(new LocalStrategy(local.options, local.authenticate))
|
||||
if (jwtPassport.options.secretOrKey) {
|
||||
_passport.use(new JwtStrategy(jwtPassport.options, jwtPassport.authenticate))
|
||||
} else {
|
||||
} else if (!env.DISABLE_JWT_WARNING) {
|
||||
logAlert("No JWT Secret supplied, cannot configure JWT strategy")
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import { structures, DBTestConfiguration } from "../../../tests"
|
||||
import {
|
||||
structures,
|
||||
DBTestConfiguration,
|
||||
expectFunctionWasCalledTimesWith,
|
||||
} from "../../../tests"
|
||||
import { Writethrough } from "../writethrough"
|
||||
import { getDB } from "../../db"
|
||||
import tk from "timekeeper"
|
||||
|
||||
const START_DATE = Date.now()
|
||||
tk.freeze(START_DATE)
|
||||
tk.freeze(Date.now())
|
||||
|
||||
const DELAY = 5000
|
||||
|
||||
|
@ -17,34 +20,99 @@ describe("writethrough", () => {
|
|||
const writethrough = new Writethrough(db, DELAY)
|
||||
const writethrough2 = new Writethrough(db2, DELAY)
|
||||
|
||||
const docId = structures.uuid()
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
describe("put", () => {
|
||||
let first: any
|
||||
let current: any
|
||||
|
||||
it("should be able to store, will go to DB", async () => {
|
||||
await config.doInTenant(async () => {
|
||||
const response = await writethrough.put({ _id: "test", value: 1 })
|
||||
const response = await writethrough.put({
|
||||
_id: docId,
|
||||
value: 1,
|
||||
})
|
||||
const output = await db.get(response.id)
|
||||
first = output
|
||||
current = output
|
||||
expect(output.value).toBe(1)
|
||||
})
|
||||
})
|
||||
|
||||
it("second put shouldn't update DB", async () => {
|
||||
await config.doInTenant(async () => {
|
||||
const response = await writethrough.put({ ...first, value: 2 })
|
||||
const response = await writethrough.put({ ...current, value: 2 })
|
||||
const output = await db.get(response.id)
|
||||
expect(first._rev).toBe(output._rev)
|
||||
expect(current._rev).toBe(output._rev)
|
||||
expect(output.value).toBe(1)
|
||||
})
|
||||
})
|
||||
|
||||
it("should put it again after delay period", async () => {
|
||||
await config.doInTenant(async () => {
|
||||
tk.freeze(START_DATE + DELAY + 1)
|
||||
const response = await writethrough.put({ ...first, value: 3 })
|
||||
tk.freeze(Date.now() + DELAY + 1)
|
||||
const response = await writethrough.put({ ...current, value: 3 })
|
||||
const output = await db.get(response.id)
|
||||
expect(response.rev).not.toBe(first._rev)
|
||||
expect(response.rev).not.toBe(current._rev)
|
||||
expect(output.value).toBe(3)
|
||||
|
||||
current = output
|
||||
})
|
||||
})
|
||||
|
||||
it("should handle parallel DB updates ignoring conflicts", async () => {
|
||||
await config.doInTenant(async () => {
|
||||
tk.freeze(Date.now() + DELAY + 1)
|
||||
const responses = await Promise.all([
|
||||
writethrough.put({ ...current, value: 4 }),
|
||||
writethrough.put({ ...current, value: 4 }),
|
||||
writethrough.put({ ...current, value: 4 }),
|
||||
])
|
||||
|
||||
const newRev = responses.map(x => x.rev).find(x => x !== current._rev)
|
||||
expect(newRev).toBeDefined()
|
||||
expect(responses.map(x => x.rev)).toEqual(
|
||||
expect.arrayContaining([current._rev, current._rev, newRev])
|
||||
)
|
||||
expectFunctionWasCalledTimesWith(
|
||||
console.warn,
|
||||
2,
|
||||
"bb-warn: Ignoring redlock conflict in write-through cache"
|
||||
)
|
||||
|
||||
const output = await db.get(current._id)
|
||||
expect(output.value).toBe(4)
|
||||
expect(output._rev).toBe(newRev)
|
||||
|
||||
current = output
|
||||
})
|
||||
})
|
||||
|
||||
it("should handle updates with documents falling behind", async () => {
|
||||
await config.doInTenant(async () => {
|
||||
tk.freeze(Date.now() + DELAY + 1)
|
||||
|
||||
const id = structures.uuid()
|
||||
await writethrough.put({ _id: id, value: 1 })
|
||||
const doc = await writethrough.get(id)
|
||||
|
||||
// Updating document
|
||||
tk.freeze(Date.now() + DELAY + 1)
|
||||
await writethrough.put({ ...doc, value: 2 })
|
||||
|
||||
// Update with the old rev value
|
||||
tk.freeze(Date.now() + DELAY + 1)
|
||||
const res = await writethrough.put({
|
||||
...doc,
|
||||
value: 3,
|
||||
})
|
||||
expect(res.ok).toBe(true)
|
||||
|
||||
const output = await db.get(id)
|
||||
expect(output.value).toBe(3)
|
||||
expect(output._rev).toBe(res.rev)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -52,8 +120,8 @@ describe("writethrough", () => {
|
|||
describe("get", () => {
|
||||
it("should be able to retrieve", async () => {
|
||||
await config.doInTenant(async () => {
|
||||
const response = await writethrough.get("test")
|
||||
expect(response.value).toBe(3)
|
||||
const response = await writethrough.get(docId)
|
||||
expect(response.value).toBe(4)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import BaseCache from "./base"
|
||||
import { getWritethroughClient } from "../redis/init"
|
||||
import { logWarn } from "../logging"
|
||||
import { Database } from "@budibase/types"
|
||||
import { Database, Document, LockName, LockType } from "@budibase/types"
|
||||
import * as locks from "../redis/redlockImpl"
|
||||
|
||||
const DEFAULT_WRITE_RATE_MS = 10000
|
||||
let CACHE: BaseCache | null = null
|
||||
|
@ -27,44 +28,62 @@ function makeCacheItem(doc: any, lastWrite: number | null = null): CacheItem {
|
|||
return { doc, lastWrite: lastWrite || Date.now() }
|
||||
}
|
||||
|
||||
export async function put(
|
||||
async function put(
|
||||
db: Database,
|
||||
doc: any,
|
||||
doc: Document,
|
||||
writeRateMs: number = DEFAULT_WRITE_RATE_MS
|
||||
) {
|
||||
const cache = await getCache()
|
||||
const key = doc._id
|
||||
let cacheItem: CacheItem | undefined = await cache.get(makeCacheKey(db, key))
|
||||
let cacheItem: CacheItem | undefined
|
||||
if (key) {
|
||||
cacheItem = await cache.get(makeCacheKey(db, key))
|
||||
}
|
||||
const updateDb = !cacheItem || cacheItem.lastWrite < Date.now() - writeRateMs
|
||||
let output = doc
|
||||
if (updateDb) {
|
||||
const writeDb = async (toWrite: any) => {
|
||||
// doc should contain the _id and _rev
|
||||
const response = await db.put(toWrite)
|
||||
output = {
|
||||
...doc,
|
||||
_id: response.id,
|
||||
_rev: response.rev,
|
||||
}
|
||||
}
|
||||
try {
|
||||
await writeDb(doc)
|
||||
} catch (err: any) {
|
||||
if (err.status !== 409) {
|
||||
throw err
|
||||
} else {
|
||||
// Swallow 409s but log them
|
||||
logWarn(`Ignoring conflict in write-through cache`)
|
||||
const lockResponse = await locks.doWithLock(
|
||||
{
|
||||
type: LockType.TRY_ONCE,
|
||||
name: LockName.PERSIST_WRITETHROUGH,
|
||||
resource: key,
|
||||
ttl: 1000,
|
||||
},
|
||||
async () => {
|
||||
const writeDb = async (toWrite: any) => {
|
||||
// doc should contain the _id and _rev
|
||||
const response = await db.put(toWrite, { force: true })
|
||||
output = {
|
||||
...doc,
|
||||
_id: response.id,
|
||||
_rev: response.rev,
|
||||
}
|
||||
}
|
||||
try {
|
||||
await writeDb(doc)
|
||||
} catch (err: any) {
|
||||
if (err.status !== 409) {
|
||||
throw err
|
||||
} else {
|
||||
// Swallow 409s but log them
|
||||
logWarn(`Ignoring conflict in write-through cache`)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
if (!lockResponse.executed) {
|
||||
logWarn(`Ignoring redlock conflict in write-through cache`)
|
||||
}
|
||||
}
|
||||
// if we are updating the DB then need to set the lastWrite to now
|
||||
cacheItem = makeCacheItem(output, updateDb ? null : cacheItem?.lastWrite)
|
||||
await cache.store(makeCacheKey(db, key), cacheItem)
|
||||
if (output._id) {
|
||||
await cache.store(makeCacheKey(db, output._id), cacheItem)
|
||||
}
|
||||
return { ok: true, id: output._id, rev: output._rev }
|
||||
}
|
||||
|
||||
export async function get(db: Database, id: string): Promise<any> {
|
||||
async function get(db: Database, id: string): Promise<any> {
|
||||
const cache = await getCache()
|
||||
const cacheKey = makeCacheKey(db, id)
|
||||
let cacheItem: CacheItem = await cache.get(cacheKey)
|
||||
|
@ -76,11 +95,7 @@ export async function get(db: Database, id: string): Promise<any> {
|
|||
return cacheItem.doc
|
||||
}
|
||||
|
||||
export async function remove(
|
||||
db: Database,
|
||||
docOrId: any,
|
||||
rev?: any
|
||||
): Promise<void> {
|
||||
async function remove(db: Database, docOrId: any, rev?: any): Promise<void> {
|
||||
const cache = await getCache()
|
||||
if (!docOrId) {
|
||||
throw new Error("No ID/Rev provided.")
|
||||
|
|
|
@ -42,7 +42,9 @@ export async function getConfig<T extends Config>(
|
|||
}
|
||||
}
|
||||
|
||||
export async function save(config: Config) {
|
||||
export async function save(
|
||||
config: Config
|
||||
): Promise<{ id: string; rev: string }> {
|
||||
const db = context.getGlobalDB()
|
||||
return db.put(config)
|
||||
}
|
||||
|
|
|
@ -94,6 +94,7 @@ const environment = {
|
|||
SMTP_HOST: process.env.SMTP_HOST,
|
||||
SMTP_PORT: parseInt(process.env.SMTP_PORT || ""),
|
||||
SMTP_FROM_ADDRESS: process.env.SMTP_FROM_ADDRESS,
|
||||
DISABLE_JWT_WARNING: process.env.DISABLE_JWT_WARNING,
|
||||
/**
|
||||
* Enable to allow an admin user to login using a password.
|
||||
* This can be useful to prevent lockout when configuring SSO.
|
||||
|
|
|
@ -24,7 +24,7 @@ const getClient = async (type: LockType): Promise<Redlock> => {
|
|||
}
|
||||
}
|
||||
|
||||
export const OPTIONS = {
|
||||
const OPTIONS = {
|
||||
TRY_ONCE: {
|
||||
// immediately throws an error if the lock is already held
|
||||
retryCount: 0,
|
||||
|
@ -56,14 +56,29 @@ export const OPTIONS = {
|
|||
},
|
||||
}
|
||||
|
||||
export const newRedlock = async (opts: Options = {}) => {
|
||||
const newRedlock = async (opts: Options = {}) => {
|
||||
let options = { ...OPTIONS.DEFAULT, ...opts }
|
||||
const redisWrapper = await getLockClient()
|
||||
const client = redisWrapper.getClient()
|
||||
return new Redlock([client], options)
|
||||
}
|
||||
|
||||
export const doWithLock = async (opts: LockOptions, task: any) => {
|
||||
type SuccessfulRedlockExecution<T> = {
|
||||
executed: true
|
||||
result: T
|
||||
}
|
||||
type UnsuccessfulRedlockExecution = {
|
||||
executed: false
|
||||
}
|
||||
|
||||
type RedlockExecution<T> =
|
||||
| SuccessfulRedlockExecution<T>
|
||||
| UnsuccessfulRedlockExecution
|
||||
|
||||
export const doWithLock = async <T>(
|
||||
opts: LockOptions,
|
||||
task: () => Promise<T>
|
||||
): Promise<RedlockExecution<T>> => {
|
||||
const redlock = await getClient(opts.type)
|
||||
let lock
|
||||
try {
|
||||
|
@ -73,8 +88,8 @@ export const doWithLock = async (opts: LockOptions, task: any) => {
|
|||
let name: string = `lock:${prefix}_${opts.name}`
|
||||
|
||||
// add additional unique name if required
|
||||
if (opts.nameSuffix) {
|
||||
name = name + `_${opts.nameSuffix}`
|
||||
if (opts.resource) {
|
||||
name = name + `_${opts.resource}`
|
||||
}
|
||||
|
||||
// create the lock
|
||||
|
@ -83,7 +98,7 @@ export const doWithLock = async (opts: LockOptions, task: any) => {
|
|||
// perform locked task
|
||||
// need to await to ensure completion before unlocking
|
||||
const result = await task()
|
||||
return result
|
||||
return { executed: true, result }
|
||||
} catch (e: any) {
|
||||
console.warn("lock error")
|
||||
// lock limit exceeded
|
||||
|
@ -92,7 +107,7 @@ export const doWithLock = async (opts: LockOptions, task: any) => {
|
|||
// don't throw for try-once locks, they will always error
|
||||
// due to retry count (0) exceeded
|
||||
console.warn(e)
|
||||
return
|
||||
return { executed: false }
|
||||
} else {
|
||||
console.error(e)
|
||||
throw e
|
||||
|
|
|
@ -4,4 +4,6 @@ export { generator } from "./structures"
|
|||
export * as testEnv from "./testEnv"
|
||||
export * as testContainerUtils from "./testContainerUtils"
|
||||
|
||||
export * from "./jestUtils"
|
||||
|
||||
export { default as DBTestConfiguration } from "./DBTestConfiguration"
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
export function expectFunctionWasCalledTimesWith(
|
||||
jestFunction: any,
|
||||
times: number,
|
||||
argument: any
|
||||
) {
|
||||
expect(
|
||||
jestFunction.mock.calls.filter((call: any) => call[0] === argument).length
|
||||
).toBe(times)
|
||||
}
|
|
@ -1,5 +1,12 @@
|
|||
import { structures } from ".."
|
||||
import { newid } from "../../../src/newid"
|
||||
|
||||
export function id() {
|
||||
return `db_${newid()}`
|
||||
}
|
||||
|
||||
export function rev() {
|
||||
return `${structures.generator.character({
|
||||
numeric: true,
|
||||
})}-${structures.uuid().replace(/-/, "")}`
|
||||
}
|
||||
|
|
|
@ -475,10 +475,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||
|
||||
"@budibase/nano@10.1.1":
|
||||
version "10.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/nano/-/nano-10.1.1.tgz#36ccda4d9bb64b5ee14dd2b27a295b40739b1038"
|
||||
integrity sha512-kbMIzMkjVtl+xI0UPwVU0/pn8/ccxTyfzwBz6Z+ZiN2oUSb0fJCe0qwA6o8dxwSa8nZu4MbGAeMJl3CJndmWtA==
|
||||
"@budibase/nano@10.1.2":
|
||||
version "10.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@budibase/nano/-/nano-10.1.2.tgz#10fae5a1ab39be6a81261f40e7b7ec6d21cbdd4a"
|
||||
integrity sha512-1w+YN2n/M5aZ9hBKCP4NEjdQbT8BfCLRizkdvm0Je665eEHw3aE1hvo8mon9Ro9QuDdxj1DfDMMFnym6/QUwpQ==
|
||||
dependencies:
|
||||
"@types/tough-cookie" "^4.0.2"
|
||||
axios "^1.1.3"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@budibase/bbui",
|
||||
"description": "A UI solution used in the different Budibase projects.",
|
||||
"version": "2.3.18-alpha.29",
|
||||
"version": "2.4.8-alpha.4",
|
||||
"license": "MPL-2.0",
|
||||
"svelte": "src/index.js",
|
||||
"module": "dist/bbui.es.js",
|
||||
|
@ -38,7 +38,8 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@adobe/spectrum-css-workflow-icons": "1.2.1",
|
||||
"@budibase/string-templates": "2.3.18-alpha.29",
|
||||
"@budibase/shared-core": "2.4.8-alpha.4",
|
||||
"@budibase/string-templates": "2.4.8-alpha.4",
|
||||
"@spectrum-css/accordion": "3.0.24",
|
||||
"@spectrum-css/actionbutton": "1.0.1",
|
||||
"@spectrum-css/actiongroup": "1.0.1",
|
||||
|
|
|
@ -113,6 +113,9 @@
|
|||
.spectrum-ActionButton--quiet {
|
||||
padding: 0 8px;
|
||||
}
|
||||
.spectrum-ActionButton--quiet.is-selected {
|
||||
color: var(--spectrum-global-color-gray-900);
|
||||
}
|
||||
.is-selected:not(.emphasized) .spectrum-Icon {
|
||||
color: var(--spectrum-global-color-gray-900);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ export default function positionDropdown(element, opts) {
|
|||
styles.top = anchorBounds.top
|
||||
} else if (window.innerHeight - anchorBounds.bottom < 100) {
|
||||
styles.top = anchorBounds.top - elementBounds.height - offset
|
||||
styles.maxHeight = 240
|
||||
} else {
|
||||
styles.top = anchorBounds.bottom + offset
|
||||
styles.maxHeight = window.innerHeight - anchorBounds.bottom - 20
|
||||
|
|
|
@ -29,6 +29,14 @@
|
|||
visible = false
|
||||
}
|
||||
|
||||
export function toggle() {
|
||||
if (visible) {
|
||||
hide()
|
||||
} else {
|
||||
show()
|
||||
}
|
||||
}
|
||||
|
||||
export function cancel() {
|
||||
if (!visible) {
|
||||
return
|
||||
|
@ -61,7 +69,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
setContext(Context.Modal, { show, hide, cancel })
|
||||
setContext(Context.Modal, { show, hide, toggle, cancel })
|
||||
|
||||
onMount(() => {
|
||||
document.addEventListener("keydown", handleKey)
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import { helpers } from "@budibase/shared-core"
|
||||
export const deepGet = helpers.deepGet
|
||||
|
||||
/**
|
||||
* Generates a DOM safe UUID.
|
||||
* Starting with a letter is important to make it DOM safe.
|
||||
|
@ -41,30 +44,6 @@ export const hashString = string => {
|
|||
return hash.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a key within an object. The key supports dot syntax for retrieving deep
|
||||
* fields - e.g. "a.b.c".
|
||||
* Exact matches of keys with dots in them take precedence over nested keys of
|
||||
* the same path - e.g. getting "a.b" from { "a.b": "foo", a: { b: "bar" } }
|
||||
* will return "foo" over "bar".
|
||||
* @param obj the object
|
||||
* @param key the key
|
||||
* @return {*|null} the value or null if a value was not found for this key
|
||||
*/
|
||||
export const deepGet = (obj, key) => {
|
||||
if (!obj || !key) {
|
||||
return null
|
||||
}
|
||||
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||
return obj[key]
|
||||
}
|
||||
const split = key.split(".")
|
||||
for (let i = 0; i < split.length; i++) {
|
||||
obj = obj?.[split[i]]
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a key within an object. The key supports dot syntax for retrieving deep
|
||||
* fields - e.g. "a.b.c".
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/builder",
|
||||
"version": "2.3.18-alpha.29",
|
||||
"version": "2.4.8-alpha.4",
|
||||
"license": "GPL-3.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
@ -58,10 +58,11 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "2.3.18-alpha.29",
|
||||
"@budibase/client": "2.3.18-alpha.29",
|
||||
"@budibase/frontend-core": "2.3.18-alpha.29",
|
||||
"@budibase/string-templates": "2.3.18-alpha.29",
|
||||
"@budibase/bbui": "2.4.8-alpha.4",
|
||||
"@budibase/client": "2.4.8-alpha.4",
|
||||
"@budibase/frontend-core": "2.4.8-alpha.4",
|
||||
"@budibase/shared-core": "2.4.8-alpha.4",
|
||||
"@budibase/string-templates": "2.4.8-alpha.4",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.2.1",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.2.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.2.1",
|
||||
|
|
|
@ -73,14 +73,14 @@
|
|||
<Tabs noHorizPadding selected="Input">
|
||||
<Tab title="Input">
|
||||
<TextArea
|
||||
minHeight="80px"
|
||||
minHeight="160px"
|
||||
disabled
|
||||
value={textArea(filteredResults?.[idx]?.inputs, "No input")}
|
||||
/>
|
||||
</Tab>
|
||||
<Tab title="Output">
|
||||
<TextArea
|
||||
minHeight="100px"
|
||||
minHeight="160px"
|
||||
disabled
|
||||
value={textArea(filteredResults?.[idx]?.outputs, "No output")}
|
||||
/>
|
||||
|
@ -98,8 +98,9 @@
|
|||
|
||||
<style>
|
||||
.container {
|
||||
padding: 0 30px 0 30px;
|
||||
padding: 0 30px 30px 30px;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
|
|
|
@ -0,0 +1,333 @@
|
|||
<script>
|
||||
import {
|
||||
Context,
|
||||
Icon,
|
||||
Input,
|
||||
ModalContent,
|
||||
Detail,
|
||||
notifications,
|
||||
} from "@budibase/bbui"
|
||||
import { API } from "api"
|
||||
import { goto } from "@roxi/routify"
|
||||
import {
|
||||
store,
|
||||
sortedScreens,
|
||||
automationStore,
|
||||
themeStore,
|
||||
} from "builderStore"
|
||||
import { datasources, queries, tables, views } from "stores/backend"
|
||||
import { getContext } from "svelte"
|
||||
import { Constants } from "@budibase/frontend-core"
|
||||
|
||||
const modalContext = getContext(Context.Modal)
|
||||
const commands = [
|
||||
{
|
||||
type: "Access",
|
||||
name: "Invite users and manage app access",
|
||||
description: "",
|
||||
icon: "User",
|
||||
action: () =>
|
||||
store.update(state => ({ ...state, builderSidePanel: true })),
|
||||
},
|
||||
{
|
||||
type: "Navigate",
|
||||
name: "Portal",
|
||||
description: "",
|
||||
icon: "Compass",
|
||||
action: () => $goto("../../portal"),
|
||||
},
|
||||
{
|
||||
type: "Navigate",
|
||||
name: "Data",
|
||||
description: "",
|
||||
icon: "Compass",
|
||||
action: () => $goto("./data"),
|
||||
},
|
||||
{
|
||||
type: "Navigate",
|
||||
name: "Design",
|
||||
description: "",
|
||||
icon: "Compass",
|
||||
action: () => $goto("./design"),
|
||||
},
|
||||
{
|
||||
type: "Navigate",
|
||||
name: "Automations",
|
||||
description: "",
|
||||
icon: "Compass",
|
||||
action: () => $goto("./automate"),
|
||||
},
|
||||
{
|
||||
type: "Publish",
|
||||
name: "App",
|
||||
description: "Deploy your application",
|
||||
icon: "Box",
|
||||
action: deployApp,
|
||||
},
|
||||
{
|
||||
type: "Preview",
|
||||
name: "App",
|
||||
description: "",
|
||||
icon: "Play",
|
||||
action: () => window.open(`/${$store.appId}`),
|
||||
},
|
||||
{
|
||||
type: "Preview",
|
||||
name: "Published App",
|
||||
icon: "Play",
|
||||
action: () => window.open(`/app${$store.url}`),
|
||||
},
|
||||
{
|
||||
type: "Support",
|
||||
name: "Raise Github Discussion",
|
||||
icon: "Help",
|
||||
action: () =>
|
||||
window.open(`https://github.com/Budibase/budibase/discussions/new`),
|
||||
},
|
||||
{
|
||||
type: "Support",
|
||||
name: "Raise A Bug",
|
||||
icon: "Bug",
|
||||
action: () =>
|
||||
window.open(
|
||||
`https://github.com/Budibase/budibase/issues/new?assignees=&labels=bug&template=bug_report.md&title=`
|
||||
),
|
||||
},
|
||||
...$datasources?.list.map(datasource => ({
|
||||
type: "Datasource",
|
||||
name: `${datasource.name}`,
|
||||
icon: "Data",
|
||||
action: () => $goto(`./data/datasource/${datasource._id}`),
|
||||
})),
|
||||
...$tables?.list.map(table => ({
|
||||
type: "Table",
|
||||
name: table.name,
|
||||
icon: "Table",
|
||||
action: () => $goto(`./data/table/${table._id}`),
|
||||
})),
|
||||
...$views?.list.map(view => ({
|
||||
type: "View",
|
||||
name: view.name,
|
||||
icon: "Remove",
|
||||
action: () => $goto(`./data/view/${view.name}`),
|
||||
})),
|
||||
...$queries?.list.map(query => ({
|
||||
type: "Query",
|
||||
name: query.name,
|
||||
icon: "SQLQuery",
|
||||
action: () => $goto(`./data/query/${query._id}`),
|
||||
})),
|
||||
...$sortedScreens.map(screen => ({
|
||||
type: "Screen",
|
||||
name: screen.routing.route,
|
||||
icon: "WebPage",
|
||||
action: () => $goto(`./design/${screen._id}/components`),
|
||||
})),
|
||||
...$automationStore?.automations.map(automation => ({
|
||||
type: "Automation",
|
||||
name: automation.name,
|
||||
icon: "ShareAndroid",
|
||||
action: () => $goto(`./automate/${automation._id}`),
|
||||
})),
|
||||
...Constants.Themes.map(theme => ({
|
||||
type: "Change Builder Theme",
|
||||
name: theme.name,
|
||||
icon: "ColorPalette",
|
||||
action: () =>
|
||||
themeStore.update(state => {
|
||||
state.theme = theme.class
|
||||
return state
|
||||
}),
|
||||
})),
|
||||
]
|
||||
|
||||
let search
|
||||
let selected = null
|
||||
|
||||
$: enrichedCommands = commands.map(cmd => ({
|
||||
...cmd,
|
||||
searchValue: `${cmd.type} ${cmd.name}`.toLowerCase(),
|
||||
}))
|
||||
$: results = filterResults(enrichedCommands, search)
|
||||
$: categories = groupResults(results)
|
||||
|
||||
const filterResults = (commands, search) => {
|
||||
if (!search) {
|
||||
selected = null
|
||||
return commands
|
||||
}
|
||||
selected = 0
|
||||
search = search.toLowerCase()
|
||||
return commands
|
||||
.filter(cmd => cmd.searchValue.includes(search))
|
||||
.map((cmd, idx) => ({
|
||||
...cmd,
|
||||
idx,
|
||||
}))
|
||||
}
|
||||
|
||||
const groupResults = results => {
|
||||
let categories = {}
|
||||
results?.forEach(result => {
|
||||
if (!categories[result.type]) {
|
||||
categories[result.type] = []
|
||||
}
|
||||
categories[result.type].push(result)
|
||||
})
|
||||
return Object.entries(categories)
|
||||
}
|
||||
|
||||
const onKeyDown = e => {
|
||||
if (e.key === "ArrowDown") {
|
||||
e.preventDefault()
|
||||
if (selected === null) {
|
||||
selected = 0
|
||||
return
|
||||
}
|
||||
if (selected < results.length - 1) {
|
||||
selected += 1
|
||||
}
|
||||
} else if (e.key === "ArrowUp") {
|
||||
e.preventDefault()
|
||||
if (selected === null) {
|
||||
selected = results.length - 1
|
||||
return
|
||||
}
|
||||
if (selected > 0) {
|
||||
selected -= 1
|
||||
}
|
||||
} else if (e.key === "Enter") {
|
||||
if (selected == null) {
|
||||
return
|
||||
}
|
||||
runAction(results[selected])
|
||||
} else if (e.key === "Escape") {
|
||||
modalContext.hide()
|
||||
}
|
||||
}
|
||||
|
||||
async function deployApp() {
|
||||
try {
|
||||
await API.deployAppChanges()
|
||||
notifications.success("Application published successfully")
|
||||
} catch (error) {
|
||||
notifications.error("Error publishing app")
|
||||
}
|
||||
}
|
||||
|
||||
const runAction = command => {
|
||||
if (!command) {
|
||||
return
|
||||
}
|
||||
command.action()
|
||||
modalContext.hide()
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={onKeyDown} />
|
||||
<ModalContent
|
||||
size="L"
|
||||
showCancelButton={false}
|
||||
showConfirmButton={false}
|
||||
showCloseIcon={false}
|
||||
>
|
||||
<div class="content">
|
||||
<div class="title">
|
||||
<Icon size="XL" name="Search" />
|
||||
<Input bind:value={search} quiet placeholder="Search for command" />
|
||||
</div>
|
||||
<div class="commands">
|
||||
{#each categories as [name, results], catIdx}
|
||||
<div class="category">
|
||||
<Detail>{name}</Detail>
|
||||
<div class="options">
|
||||
{#each results as command, cmdIdx}
|
||||
<div
|
||||
class="command"
|
||||
on:click={() => runAction(command)}
|
||||
class:selected={command.idx === selected}
|
||||
>
|
||||
<Icon size="M" name={command.icon} />
|
||||
<strong>{command.type}: </strong>
|
||||
<div class="name">
|
||||
{command.name}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</ModalContent>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
margin: -40px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.title {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding: var(--spacing-xl) var(--spacing-xl) var(--spacing-l)
|
||||
var(--spacing-xl);
|
||||
border-bottom: var(--border-dark);
|
||||
gap: var(--spacing-m);
|
||||
border-bottom-width: 2px;
|
||||
}
|
||||
.title :global(.spectrum-Textfield-input) {
|
||||
border-bottom: none;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.commands {
|
||||
height: 378px;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.category {
|
||||
padding: var(--spacing-m) var(--spacing-xl);
|
||||
border-bottom: var(--border-light);
|
||||
}
|
||||
.category:last-of-type {
|
||||
border-bottom: none;
|
||||
}
|
||||
.category :global(.spectrum-Detail) {
|
||||
color: var(--spectrum-global-color-gray-600);
|
||||
}
|
||||
.options {
|
||||
padding-top: var(--spacing-m);
|
||||
margin: 0 calc(-1 * var(--spacing-xl));
|
||||
}
|
||||
|
||||
.command {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding: var(--spacing-s) var(--spacing-xl);
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
transition: color 130ms ease-out, background-color 130ms ease-out;
|
||||
}
|
||||
.command:hover,
|
||||
.selected {
|
||||
color: var(--spectrum-global-color-gray-900);
|
||||
background-color: var(--spectrum-global-color-gray-300);
|
||||
}
|
||||
.command strong {
|
||||
margin-left: var(--spacing-m);
|
||||
}
|
||||
.name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
footer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
|
@ -24,7 +24,10 @@
|
|||
let updateModal
|
||||
|
||||
$: appId = $store.appId
|
||||
$: updateAvailable = clientPackage.version !== $store.version
|
||||
$: updateAvailable =
|
||||
clientPackage.version &&
|
||||
$store.version &&
|
||||
clientPackage.version !== $store.version
|
||||
$: revertAvailable = $store.revertableVersion != null
|
||||
|
||||
const refreshAppPackage = async () => {
|
||||
|
|
|
@ -14,10 +14,11 @@
|
|||
export let borderRight = false
|
||||
|
||||
let wide = false
|
||||
$: customHeaderContent = $$slots["panel-header-content"]
|
||||
</script>
|
||||
|
||||
<div class="panel" class:wide class:borderLeft class:borderRight>
|
||||
<div class="header">
|
||||
<div class="header" class:custom={customHeaderContent}>
|
||||
{#if showBackButton}
|
||||
<Icon name="ArrowLeft" hoverable on:click={onClickBackButton} />
|
||||
{/if}
|
||||
|
@ -43,6 +44,13 @@
|
|||
<Icon name="Close" hoverable on:click={onClickCloseButton} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if customHeaderContent}
|
||||
<span class="custom-content-wrap">
|
||||
<slot name="panel-header-content" />
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
<div class="body">
|
||||
<slot />
|
||||
</div>
|
||||
|
@ -116,4 +124,10 @@
|
|||
justify-content: flex-start;
|
||||
align-items: stretch;
|
||||
}
|
||||
.header.custom {
|
||||
border: none;
|
||||
}
|
||||
.custom-content-wrap {
|
||||
border-bottom: var(--border-light);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -20,6 +20,12 @@
|
|||
x =>
|
||||
x._id !== BUDIBASE_INTERNAL_DB_ID && x.type !== BUDIBASE_DATASOURCE_TYPE
|
||||
)
|
||||
// Ensure query params exist so they can be bound
|
||||
$: {
|
||||
if (!parameters.queryParams) {
|
||||
parameters.queryParams = {}
|
||||
}
|
||||
}
|
||||
|
||||
function fetchQueryDefinition(query) {
|
||||
const source = $datasources.list.find(
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
getSchemaForDatasource,
|
||||
} from "builderStore/dataBinding"
|
||||
import { currentAsset } from "builderStore"
|
||||
import { getFields } from "helpers/searchFields"
|
||||
|
||||
export let componentInstance
|
||||
export let value = []
|
||||
|
@ -21,9 +22,14 @@
|
|||
|
||||
$: datasource = getDatasourceForProvider($currentAsset, componentInstance)
|
||||
$: schema = getSchema($currentAsset, datasource)
|
||||
$: options = Object.keys(schema || {})
|
||||
$: options = allowCellEditing
|
||||
? Object.keys(schema || {})
|
||||
: enrichedSchemaFields?.map(field => field.name)
|
||||
$: sanitisedValue = getValidColumns(value, options)
|
||||
$: updateBoundValue(sanitisedValue)
|
||||
$: enrichedSchemaFields = getFields(Object.values(schema) || [], {
|
||||
allowLinks: true,
|
||||
})
|
||||
|
||||
const getSchema = (asset, datasource) => {
|
||||
const schema = getSchemaForDatasource(asset, datasource).schema
|
||||
|
|
|
@ -120,7 +120,7 @@
|
|||
|
||||
const cleanUrl = inputUrl =>
|
||||
url
|
||||
?.replace(/(http)|(https)|[{}:]/g, "")
|
||||
?.replace(/(https)|(http)|[{}:]/g, "")
|
||||
?.replaceAll(".", "_")
|
||||
?.replaceAll("/", " ")
|
||||
?.trim() || inputUrl
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { get } from "svelte/store"
|
||||
import { store } from "builderStore"
|
||||
import { users, auth } from "stores/portal"
|
||||
import { auth } from "stores/portal"
|
||||
import analytics from "analytics"
|
||||
import { OnboardingData, OnboardingDesign, OnboardingPublish } from "./steps"
|
||||
import { API } from "api"
|
||||
const ONBOARDING_EVENT_PREFIX = "onboarding"
|
||||
|
||||
export const TOUR_STEP_KEYS = {
|
||||
|
@ -83,8 +84,7 @@ const getTours = () => {
|
|||
// Mark the users onboarding as complete
|
||||
// Clear all tour related state
|
||||
if (get(auth).user) {
|
||||
await users.save({
|
||||
...get(auth).user,
|
||||
await API.updateSelf({
|
||||
onboardedAt: new Date().toISOString(),
|
||||
})
|
||||
|
||||
|
@ -114,8 +114,7 @@ const getTours = () => {
|
|||
onComplete: async () => {
|
||||
// Push the onboarding forward
|
||||
if (get(auth).user) {
|
||||
await users.save({
|
||||
...get(auth).user,
|
||||
await API.updateSelf({
|
||||
onboardedAt: new Date().toISOString(),
|
||||
})
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
await auth.updateSelf($values)
|
||||
notifications.success("Information updated successfully")
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
notifications.error("Failed to update information")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
return list.map(item => {
|
||||
return {
|
||||
...item,
|
||||
selected: selected.find(x => x === item._id) != null,
|
||||
selected: selected?.find(x => x === item._id) != null,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -346,8 +346,15 @@
|
|||
|
||||
onMount(() => {
|
||||
rendered = true
|
||||
searchFocus = true
|
||||
})
|
||||
|
||||
function handleKeyDown(evt) {
|
||||
if (evt.key === "Enter" && queryIsEmail && !inviting) {
|
||||
onInviteUser()
|
||||
}
|
||||
}
|
||||
|
||||
const userTitle = user => {
|
||||
if (user.admin?.global) {
|
||||
return "Admin"
|
||||
|
@ -370,6 +377,8 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={handleKeyDown} />
|
||||
|
||||
<div
|
||||
id="builder-side-panel-container"
|
||||
class:open={$store.builderSidePanel}
|
||||
|
@ -403,6 +412,7 @@
|
|||
autocomplete="off"
|
||||
disabled={inviting}
|
||||
value={query}
|
||||
autofocus
|
||||
on:input={e => {
|
||||
query = e.target.value.trim()
|
||||
}}
|
||||
|
@ -661,6 +671,7 @@
|
|||
align-items: center;
|
||||
gap: var(--spacing-m);
|
||||
color: var(--spectrum-global-color-gray-900);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.auth-entity .user-email {
|
||||
|
@ -741,11 +752,11 @@
|
|||
}
|
||||
|
||||
.builder-side-panel-header {
|
||||
height: 58px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex: 0 0 58px;
|
||||
}
|
||||
|
||||
.invite-header {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
Tabs,
|
||||
Tab,
|
||||
Heading,
|
||||
Modal,
|
||||
notifications,
|
||||
} from "@budibase/bbui"
|
||||
|
||||
|
@ -18,6 +19,7 @@
|
|||
import { isActive, goto, layout, redirect } from "@roxi/routify"
|
||||
import { capitalise } from "helpers"
|
||||
import { onMount, onDestroy } from "svelte"
|
||||
import CommandPalette from "components/commandPalette/CommandPalette.svelte"
|
||||
import TourWrap from "components/portal/onboarding/TourWrap.svelte"
|
||||
import TourPopover from "components/portal/onboarding/TourPopover.svelte"
|
||||
import BuilderSidePanel from "./_components/BuilderSidePanel.svelte"
|
||||
|
@ -25,12 +27,9 @@
|
|||
|
||||
export let application
|
||||
|
||||
// Get Package and set store
|
||||
let promise = getPackage()
|
||||
// let betaAccess = false
|
||||
|
||||
// Sync once when you load the app
|
||||
let hasSynced = false
|
||||
let commandPaletteModal
|
||||
|
||||
$: selected = capitalise(
|
||||
$layout.children.find(layout => $isActive(layout.path))?.title ?? "data"
|
||||
|
@ -50,7 +49,6 @@
|
|||
$redirect("../../")
|
||||
}
|
||||
}
|
||||
|
||||
// Handles navigation between frontend, backend, automation.
|
||||
// This remembers your last place on each of the sections
|
||||
// e.g. if one of your screens is selected on front end, then
|
||||
|
@ -67,6 +65,14 @@
|
|||
})
|
||||
}
|
||||
|
||||
// Event handler for the command palette
|
||||
const handleKeyDown = e => {
|
||||
if (e.key === "k" && (e.ctrlKey || e.metaKey)) {
|
||||
e.preventDefault()
|
||||
commandPaletteModal.toggle()
|
||||
}
|
||||
}
|
||||
|
||||
const initTour = async () => {
|
||||
// Check if onboarding is enabled.
|
||||
if (isEnabled(TENANT_FEATURE_FLAGS.ONBOARDING_TOUR)) {
|
||||
|
@ -120,89 +126,91 @@
|
|||
})
|
||||
</script>
|
||||
|
||||
{#await promise}
|
||||
<!-- This should probably be some kind of loading state? -->
|
||||
<div class="loading" />
|
||||
{:then _}
|
||||
<TourPopover />
|
||||
<TourPopover />
|
||||
|
||||
{#if $store.builderSidePanel}
|
||||
<BuilderSidePanel />
|
||||
{/if}
|
||||
{#if $store.builderSidePanel}
|
||||
<BuilderSidePanel />
|
||||
{/if}
|
||||
|
||||
<div class="root">
|
||||
<div class="top-nav">
|
||||
<div class="topleftnav">
|
||||
<ActionMenu>
|
||||
<div slot="control">
|
||||
<Icon size="M" hoverable name="ShowMenu" />
|
||||
</div>
|
||||
<MenuItem on:click={() => $goto("../../portal/apps")}>
|
||||
Exit to portal
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
on:click={() => $goto(`../../portal/overview/${application}`)}
|
||||
>
|
||||
Overview
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
on:click={() =>
|
||||
$goto(`../../portal/overview/${application}/access`)}
|
||||
>
|
||||
Access
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
on:click={() =>
|
||||
$goto(`../../portal/overview/${application}/automation-history`)}
|
||||
>
|
||||
Automation history
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
on:click={() =>
|
||||
$goto(`../../portal/overview/${application}/backups`)}
|
||||
>
|
||||
Backups
|
||||
</MenuItem>
|
||||
<div class="root">
|
||||
<div class="top-nav">
|
||||
<div class="topleftnav">
|
||||
<ActionMenu>
|
||||
<div slot="control">
|
||||
<Icon size="M" hoverable name="ShowMenu" />
|
||||
</div>
|
||||
<MenuItem on:click={() => $goto("../../portal/apps")}>
|
||||
Exit to portal
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
on:click={() => $goto(`../../portal/overview/${application}`)}
|
||||
>
|
||||
Overview
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
on:click={() => $goto(`../../portal/overview/${application}/access`)}
|
||||
>
|
||||
Access
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
on:click={() =>
|
||||
$goto(`../../portal/overview/${application}/automation-history`)}
|
||||
>
|
||||
Automation history
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
on:click={() => $goto(`../../portal/overview/${application}/backups`)}
|
||||
>
|
||||
Backups
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem
|
||||
on:click={() =>
|
||||
$goto(`../../portal/overview/${application}/name-and-url`)}
|
||||
>
|
||||
Name and URL
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
on:click={() =>
|
||||
$goto(`../../portal/overview/${application}/version`)}
|
||||
>
|
||||
Version
|
||||
</MenuItem>
|
||||
</ActionMenu>
|
||||
<Heading size="XS">{$store.name || "App"}</Heading>
|
||||
</div>
|
||||
<div class="topcenternav">
|
||||
<Tabs {selected} size="M">
|
||||
{#each $layout.children as { path, title }}
|
||||
<TourWrap tourStepKey={`builder-${title}-section`}>
|
||||
<Tab
|
||||
quiet
|
||||
selected={$isActive(path)}
|
||||
on:click={topItemNavigate(path)}
|
||||
title={capitalise(title)}
|
||||
id={`builder-${title}-tab`}
|
||||
/>
|
||||
</TourWrap>
|
||||
{/each}
|
||||
</Tabs>
|
||||
</div>
|
||||
<div class="toprightnav">
|
||||
<AppActions {application} />
|
||||
</div>
|
||||
<MenuItem
|
||||
on:click={() =>
|
||||
$goto(`../../portal/overview/${application}/name-and-url`)}
|
||||
>
|
||||
Name and URL
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
on:click={() => $goto(`../../portal/overview/${application}/version`)}
|
||||
>
|
||||
Version
|
||||
</MenuItem>
|
||||
</ActionMenu>
|
||||
<Heading size="XS">{$store.name}</Heading>
|
||||
</div>
|
||||
<div class="topcenternav">
|
||||
<Tabs {selected} size="M">
|
||||
{#each $layout.children as { path, title }}
|
||||
<TourWrap tourStepKey={`builder-${title}-section`}>
|
||||
<Tab
|
||||
quiet
|
||||
selected={$isActive(path)}
|
||||
on:click={topItemNavigate(path)}
|
||||
title={capitalise(title)}
|
||||
id={`builder-${title}-tab`}
|
||||
/>
|
||||
</TourWrap>
|
||||
{/each}
|
||||
</Tabs>
|
||||
</div>
|
||||
<div class="toprightnav">
|
||||
<AppActions {application} />
|
||||
</div>
|
||||
<slot />
|
||||
</div>
|
||||
{:catch error}
|
||||
<p>Something went wrong: {error.message}</p>
|
||||
{/await}
|
||||
{#await promise}
|
||||
<!-- This should probably be some kind of loading state? -->
|
||||
<div class="loading" />
|
||||
{:then _}
|
||||
<slot />
|
||||
{:catch error}
|
||||
<p>Something went wrong: {error.message}</p>
|
||||
{/await}
|
||||
</div>
|
||||
|
||||
<svelte:window on:keydown={handleKeyDown} />
|
||||
<Modal bind:this={commandPaletteModal}>
|
||||
<CommandPalette />
|
||||
</Modal>
|
||||
|
||||
<style>
|
||||
.loading {
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
{#if duplicates?.length}
|
||||
<div class="alert-wrap">
|
||||
<Banner type="warning" showCloseButton={false}>
|
||||
{`Schema Invalid - There are duplicate auto column types defined in this schema.
|
||||
Please delete the duplicate entries where appropriate: -
|
||||
{`Schema Invalid - There are duplicate auto column types defined in this schema.
|
||||
Please delete the duplicate entries where appropriate: -
|
||||
${invalidColumnText.join(", ")}`}
|
||||
</Banner>
|
||||
</div>
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
getBindableProperties,
|
||||
getComponentBindableProperties,
|
||||
} from "builderStore/dataBinding"
|
||||
import { ActionButton } from "@budibase/bbui"
|
||||
import { capitalise } from "helpers"
|
||||
|
||||
$: componentInstance = $selectedComponent
|
||||
$: componentDefinition = store.actions.components.getDefinition(
|
||||
|
@ -25,32 +27,69 @@
|
|||
)
|
||||
$: isScreen = $selectedComponent?._id === $selectedScreen?.props._id
|
||||
$: title = isScreen ? "Screen" : $selectedComponent?._instanceName
|
||||
|
||||
let section = "settings"
|
||||
const tabs = ["settings", "styles", "conditions"]
|
||||
|
||||
$: id = $selectedComponent?._id
|
||||
$: id, (section = tabs[0])
|
||||
</script>
|
||||
|
||||
{#if $selectedComponent}
|
||||
{#key $selectedComponent._id}
|
||||
<Panel {title} icon={componentDefinition?.icon} borderLeft>
|
||||
{#if componentDefinition?.info}
|
||||
<ComponentInfoSection {componentDefinition} />
|
||||
<span slot="panel-header-content">
|
||||
<div class="settings-tabs">
|
||||
{#each tabs as tab}
|
||||
<ActionButton
|
||||
size="M"
|
||||
quiet
|
||||
selected={section === tab}
|
||||
on:click={() => {
|
||||
section = tab
|
||||
}}
|
||||
>
|
||||
{capitalise(tab)}
|
||||
</ActionButton>
|
||||
{/each}
|
||||
</div>
|
||||
</span>
|
||||
{#if section == "settings"}
|
||||
{#if componentDefinition?.info}
|
||||
<ComponentInfoSection {componentDefinition} />
|
||||
{/if}
|
||||
<ComponentSettingsSection
|
||||
{componentInstance}
|
||||
{componentDefinition}
|
||||
{bindings}
|
||||
{componentBindings}
|
||||
{isScreen}
|
||||
/>
|
||||
{/if}
|
||||
{#if section == "styles"}
|
||||
<DesignSection {componentInstance} {componentDefinition} {bindings} />
|
||||
<CustomStylesSection
|
||||
{componentInstance}
|
||||
{componentDefinition}
|
||||
{bindings}
|
||||
/>
|
||||
{/if}
|
||||
{#if section == "conditions"}
|
||||
<ConditionalUISection
|
||||
{componentInstance}
|
||||
{componentDefinition}
|
||||
{bindings}
|
||||
/>
|
||||
{/if}
|
||||
<ComponentSettingsSection
|
||||
{componentInstance}
|
||||
{componentDefinition}
|
||||
{bindings}
|
||||
{componentBindings}
|
||||
{isScreen}
|
||||
/>
|
||||
<DesignSection {componentInstance} {componentDefinition} {bindings} />
|
||||
<CustomStylesSection
|
||||
{componentInstance}
|
||||
{componentDefinition}
|
||||
{bindings}
|
||||
/>
|
||||
<ConditionalUISection
|
||||
{componentInstance}
|
||||
{componentDefinition}
|
||||
{bindings}
|
||||
/>
|
||||
</Panel>
|
||||
{/key}
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.settings-tabs {
|
||||
display: flex;
|
||||
gap: var(--spacing-s);
|
||||
padding: 0 var(--spacing-l);
|
||||
padding-bottom: var(--spacing-l);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<script>
|
||||
import { Button } from "@budibase/bbui"
|
||||
import { goto } from "@roxi/routify"
|
||||
import { auth, admin } from "stores/portal"
|
||||
import { auth, admin, licensing } from "stores/portal"
|
||||
import { isEnabled, TENANT_FEATURE_FLAGS } from "helpers/featureFlags"
|
||||
</script>
|
||||
|
||||
{#if isEnabled(TENANT_FEATURE_FLAGS.LICENSING)}
|
||||
{#if isEnabled(TENANT_FEATURE_FLAGS.LICENSING) && !$licensing.isEnterprisePlan}
|
||||
{#if $admin.cloud && $auth?.user?.accountPortalAccess}
|
||||
<Button
|
||||
cta
|
||||
|
|
|
@ -154,9 +154,14 @@ export function createAuthStore() {
|
|||
await setInitInfo({})
|
||||
},
|
||||
updateSelf: async fields => {
|
||||
const newUser = { ...get(auth).user, ...fields }
|
||||
await API.updateSelf(newUser)
|
||||
setUser(newUser)
|
||||
await API.updateSelf({ ...fields })
|
||||
// Refetch to enrich after update.
|
||||
try {
|
||||
const user = await API.fetchBuilderSelf()
|
||||
setUser(user)
|
||||
} catch (error) {
|
||||
setUser(null)
|
||||
}
|
||||
},
|
||||
forgotPassword: async email => {
|
||||
const tenantId = get(store).tenantId
|
||||
|
|
|
@ -12,6 +12,7 @@ export const createLicensingStore = () => {
|
|||
// the top level license
|
||||
license: undefined,
|
||||
isFreePlan: true,
|
||||
isEnterprisePlan: true,
|
||||
// features
|
||||
groupsEnabled: false,
|
||||
backupsEnabled: false,
|
||||
|
@ -53,7 +54,9 @@ export const createLicensingStore = () => {
|
|||
},
|
||||
setLicense: () => {
|
||||
const license = get(auth).user.license
|
||||
const isFreePlan = license?.plan.type === Constants.PlanType.FREE
|
||||
const planType = license?.plan.type
|
||||
const isEnterprisePlan = planType === Constants.PlanType.ENTERPRISE
|
||||
const isFreePlan = planType === Constants.PlanType.FREE
|
||||
const groupsEnabled = license.features.includes(
|
||||
Constants.Features.USER_GROUPS
|
||||
)
|
||||
|
@ -74,6 +77,7 @@ export const createLicensingStore = () => {
|
|||
return {
|
||||
...state,
|
||||
license,
|
||||
isEnterprisePlan,
|
||||
isFreePlan,
|
||||
groupsEnabled,
|
||||
backupsEnabled,
|
||||
|
|
|
@ -6,3 +6,4 @@ docker-error.log
|
|||
envoy.yaml
|
||||
*.tar.gz
|
||||
prebuilds/
|
||||
dist/
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
{
|
||||
"name": "@budibase/cli",
|
||||
"version": "2.3.18-alpha.29",
|
||||
"version": "2.4.8-alpha.4",
|
||||
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
||||
"main": "src/index.js",
|
||||
"main": "dist/index.js",
|
||||
"bin": {
|
||||
"budi": "src/index.js"
|
||||
"budi": "dist/index.js"
|
||||
},
|
||||
"author": "Budibase",
|
||||
"license": "GPL-3.0",
|
||||
"scripts": {
|
||||
"prebuild": "rm -rf prebuilds 2> /dev/null && cp -r node_modules/leveldown/prebuilds prebuilds",
|
||||
"build": "yarn prebuild && renamer --find .node --replace .fake 'prebuilds/**' && pkg . --out-path build && yarn postbuild",
|
||||
"rename": "renamer --find .node --replace .fake 'prebuilds/**'",
|
||||
"tsc": "tsc -p tsconfig.build.json",
|
||||
"pkg": "pkg . --out-path build --no-bytecode --public --public-packages \"*\" -C GZip",
|
||||
"build": "yarn prebuild && yarn rename && yarn tsc && yarn pkg && yarn postbuild",
|
||||
"postbuild": "rm -rf prebuilds 2> /dev/null"
|
||||
},
|
||||
"pkg": {
|
||||
|
@ -26,21 +29,21 @@
|
|||
"outputPath": "build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/backend-core": "2.3.18-alpha.29",
|
||||
"@budibase/string-templates": "2.3.18-alpha.29",
|
||||
"@budibase/types": "2.3.18-alpha.29",
|
||||
"@budibase/backend-core": "2.4.8-alpha.4",
|
||||
"@budibase/string-templates": "2.4.8-alpha.4",
|
||||
"@budibase/types": "2.4.8-alpha.4",
|
||||
"axios": "0.21.2",
|
||||
"chalk": "4.1.0",
|
||||
"cli-progress": "3.11.2",
|
||||
"commander": "7.1.0",
|
||||
"docker-compose": "0.23.6",
|
||||
"docker-compose": "0.23.12",
|
||||
"dotenv": "16.0.1",
|
||||
"download": "8.0.0",
|
||||
"find-free-port": "^2.0.0",
|
||||
"inquirer": "8.0.0",
|
||||
"joi": "17.6.0",
|
||||
"lookpath": "1.1.0",
|
||||
"node-fetch": "2",
|
||||
"node-fetch": "2.6.7",
|
||||
"pkg": "5.8.0",
|
||||
"posthog-node": "1.0.7",
|
||||
"pouchdb": "7.3.0",
|
||||
|
@ -50,8 +53,15 @@
|
|||
"yaml": "^2.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@swc/core": "^1.3.25",
|
||||
"@swc/jest": "^0.2.24",
|
||||
"@types/jest": "^29.4.0",
|
||||
"@types/node-fetch": "2.6.1",
|
||||
"@types/pouchdb": "^6.4.0",
|
||||
"copyfiles": "^2.4.1",
|
||||
"eslint": "^7.20.0",
|
||||
"renamer": "^4.0.0"
|
||||
"renamer": "^4.0.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "4.7.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
const PostHog = require("posthog-node")
|
||||
const { POSTHOG_TOKEN, AnalyticsEvents } = require("../constants")
|
||||
const ConfigManager = require("../structures/ConfigManager")
|
||||
|
||||
class AnalyticsClient {
|
||||
constructor() {
|
||||
this.client = new PostHog(POSTHOG_TOKEN)
|
||||
this.configManager = new ConfigManager()
|
||||
}
|
||||
|
||||
capture(event) {
|
||||
if (this.configManager.config.analyticsDisabled) return
|
||||
|
||||
this.client.capture(event)
|
||||
}
|
||||
|
||||
enable() {
|
||||
this.configManager.removeKey("analyticsDisabled")
|
||||
this.client.capture({ event: AnalyticsEvents.OptIn, distinctId: "cli" })
|
||||
}
|
||||
|
||||
disable() {
|
||||
this.client.capture({ event: AnalyticsEvents.OptOut, distinctId: "cli" })
|
||||
this.configManager.setValue("analyticsDisabled", true)
|
||||
}
|
||||
|
||||
status() {
|
||||
return this.configManager.config.analyticsDisabled ? "disabled" : "enabled"
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AnalyticsClient
|
|
@ -0,0 +1,33 @@
|
|||
import PostHog from "posthog-node"
|
||||
import { POSTHOG_TOKEN, AnalyticsEvent } from "../constants"
|
||||
import { ConfigManager } from "../structures/ConfigManager"
|
||||
|
||||
export class AnalyticsClient {
|
||||
client: PostHog
|
||||
configManager: ConfigManager
|
||||
|
||||
constructor() {
|
||||
this.client = new PostHog(POSTHOG_TOKEN, {})
|
||||
this.configManager = new ConfigManager()
|
||||
}
|
||||
|
||||
capture(event: { distinctId: string; event: string; properties?: any }) {
|
||||
if (this.configManager.config.analyticsDisabled) return
|
||||
|
||||
this.client.capture(event)
|
||||
}
|
||||
|
||||
enable() {
|
||||
this.configManager.removeKey("analyticsDisabled")
|
||||
this.client.capture({ event: AnalyticsEvent.OptIn, distinctId: "cli" })
|
||||
}
|
||||
|
||||
disable() {
|
||||
this.client.capture({ event: AnalyticsEvent.OptOut, distinctId: "cli" })
|
||||
this.configManager.setValue("analyticsDisabled", true)
|
||||
}
|
||||
|
||||
status() {
|
||||
return this.configManager.config.analyticsDisabled ? "disabled" : "enabled"
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
const Command = require("../structures/Command")
|
||||
const { CommandWords } = require("../constants")
|
||||
const { success, error } = require("../utils")
|
||||
const AnalyticsClient = require("./Client")
|
||||
import { Command } from "../structures/Command"
|
||||
import { CommandWord } from "../constants"
|
||||
import { success, error } from "../utils"
|
||||
import { AnalyticsClient } from "./Client"
|
||||
|
||||
const client = new AnalyticsClient()
|
||||
|
||||
|
@ -14,11 +14,10 @@ async function optOut() {
|
|||
"Successfully opted out of Budibase analytics. You can opt in at any time by running 'budi analytics opt-in'"
|
||||
)
|
||||
)
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
console.log(
|
||||
error(
|
||||
"Error opting out of Budibase analytics. Please try again later.",
|
||||
err
|
||||
`Error opting out of Budibase analytics. Please try again later - ${err}`
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -50,7 +49,7 @@ async function status() {
|
|||
}
|
||||
}
|
||||
|
||||
const command = new Command(`${CommandWords.ANALYTICS}`)
|
||||
export default new Command(`${CommandWord.ANALYTICS}`)
|
||||
.addHelp("Control the analytics you send to Budibase.")
|
||||
.addSubOption("--optin", "Opt in to sending analytics to Budibase", optIn)
|
||||
.addSubOption("--optout", "Opt out of sending analytics to Budibase.", optOut)
|
||||
|
@ -59,5 +58,3 @@ const command = new Command(`${CommandWords.ANALYTICS}`)
|
|||
"Check whether you are currently opted in to Budibase analytics.",
|
||||
status
|
||||
)
|
||||
|
||||
exports.command = command
|
|
@ -1,28 +1,30 @@
|
|||
const Command = require("../structures/Command")
|
||||
const { CommandWords } = require("../constants")
|
||||
const fs = require("fs")
|
||||
const { join } = require("path")
|
||||
const { getAllDbs } = require("../core/db")
|
||||
const tar = require("tar")
|
||||
const { progressBar, httpCall } = require("../utils")
|
||||
const {
|
||||
import { Command } from "../structures/Command"
|
||||
import { CommandWord } from "../constants"
|
||||
import fs from "fs"
|
||||
import { join } from "path"
|
||||
import { getAllDbs } from "../core/db"
|
||||
import { progressBar, httpCall } from "../utils"
|
||||
import {
|
||||
TEMP_DIR,
|
||||
COUCH_DIR,
|
||||
MINIO_DIR,
|
||||
getConfig,
|
||||
replication,
|
||||
getPouches,
|
||||
} = require("./utils")
|
||||
const { exportObjects, importObjects } = require("./objectStore")
|
||||
} from "./utils"
|
||||
import { exportObjects, importObjects } from "./objectStore"
|
||||
const tar = require("tar")
|
||||
|
||||
async function exportBackup(opts) {
|
||||
type BackupOpts = { env?: string; import?: string; export?: string }
|
||||
|
||||
async function exportBackup(opts: BackupOpts) {
|
||||
const envFile = opts.env || undefined
|
||||
let filename = opts["export"] || opts
|
||||
let filename = opts["export"] || (opts as string)
|
||||
if (typeof filename !== "string") {
|
||||
filename = `backup-${new Date().toISOString()}.tar.gz`
|
||||
}
|
||||
const config = await getConfig(envFile)
|
||||
const dbList = await getAllDbs(config["COUCH_DB_URL"])
|
||||
const dbList = (await getAllDbs(config["COUCH_DB_URL"])) as string[]
|
||||
const { Remote, Local } = getPouches(config)
|
||||
if (fs.existsSync(TEMP_DIR)) {
|
||||
fs.rmSync(TEMP_DIR, { recursive: true })
|
||||
|
@ -55,9 +57,9 @@ async function exportBackup(opts) {
|
|||
console.log(`Generated export file - ${filename}`)
|
||||
}
|
||||
|
||||
async function importBackup(opts) {
|
||||
async function importBackup(opts: BackupOpts) {
|
||||
const envFile = opts.env || undefined
|
||||
const filename = opts["import"] || opts
|
||||
const filename = opts["import"] || (opts as string)
|
||||
const config = await getConfig(envFile)
|
||||
if (!filename || !fs.existsSync(filename)) {
|
||||
console.error("Cannot import without specifying a valid file to import")
|
||||
|
@ -99,7 +101,7 @@ async function importBackup(opts) {
|
|||
fs.rmSync(TEMP_DIR, { recursive: true })
|
||||
}
|
||||
|
||||
async function pickOne(opts) {
|
||||
async function pickOne(opts: BackupOpts) {
|
||||
if (opts["import"]) {
|
||||
return importBackup(opts)
|
||||
} else if (opts["export"]) {
|
||||
|
@ -107,7 +109,7 @@ async function pickOne(opts) {
|
|||
}
|
||||
}
|
||||
|
||||
const command = new Command(`${CommandWords.BACKUPS}`)
|
||||
export default new Command(`${CommandWord.BACKUPS}`)
|
||||
.addHelp(
|
||||
"Allows building backups of Budibase, as well as importing a backup to a new instance."
|
||||
)
|
||||
|
@ -126,5 +128,3 @@ const command = new Command(`${CommandWords.BACKUPS}`)
|
|||
"Provide an environment variable file to configure the CLI.",
|
||||
pickOne
|
||||
)
|
||||
|
||||
exports.command = command
|
|
@ -1,8 +1,8 @@
|
|||
const { objectStore } = require("@budibase/backend-core")
|
||||
const fs = require("fs")
|
||||
const { join } = require("path")
|
||||
const { TEMP_DIR, MINIO_DIR } = require("./utils")
|
||||
const { progressBar } = require("../utils")
|
||||
import { objectStore } from "@budibase/backend-core"
|
||||
import fs from "fs"
|
||||
import { join } from "path"
|
||||
import { TEMP_DIR, MINIO_DIR } from "./utils"
|
||||
import { progressBar } from "../utils"
|
||||
const {
|
||||
ObjectStoreBuckets,
|
||||
ObjectStore,
|
||||
|
@ -13,10 +13,10 @@ const {
|
|||
|
||||
const bucketList = Object.values(ObjectStoreBuckets)
|
||||
|
||||
exports.exportObjects = async () => {
|
||||
export async function exportObjects() {
|
||||
const path = join(TEMP_DIR, MINIO_DIR)
|
||||
fs.mkdirSync(path)
|
||||
let fullList = []
|
||||
let fullList: any[] = []
|
||||
let errorCount = 0
|
||||
for (let bucket of bucketList) {
|
||||
const client = ObjectStore(bucket)
|
||||
|
@ -26,7 +26,7 @@ exports.exportObjects = async () => {
|
|||
errorCount++
|
||||
continue
|
||||
}
|
||||
const list = await client.listObjectsV2().promise()
|
||||
const list = (await client.listObjectsV2().promise()) as { Contents: any[] }
|
||||
fullList = fullList.concat(list.Contents.map(el => ({ ...el, bucket })))
|
||||
}
|
||||
if (errorCount === bucketList.length) {
|
||||
|
@ -48,7 +48,7 @@ exports.exportObjects = async () => {
|
|||
bar.stop()
|
||||
}
|
||||
|
||||
exports.importObjects = async () => {
|
||||
export async function importObjects() {
|
||||
const path = join(TEMP_DIR, MINIO_DIR)
|
||||
const buckets = fs.readdirSync(path)
|
||||
let total = 0
|
|
@ -1,12 +1,13 @@
|
|||
const dotenv = require("dotenv")
|
||||
const fs = require("fs")
|
||||
const { string } = require("../questions")
|
||||
const { getPouch } = require("../core/db")
|
||||
const { env: environment } = require("@budibase/backend-core")
|
||||
import dotenv from "dotenv"
|
||||
import fs from "fs"
|
||||
import { string } from "../questions"
|
||||
import { getPouch } from "../core/db"
|
||||
import { env as environment } from "@budibase/backend-core"
|
||||
import PouchDB from "pouchdb"
|
||||
|
||||
exports.TEMP_DIR = ".temp"
|
||||
exports.COUCH_DIR = "couchdb"
|
||||
exports.MINIO_DIR = "minio"
|
||||
export const TEMP_DIR = ".temp"
|
||||
export const COUCH_DIR = "couchdb"
|
||||
export const MINIO_DIR = "minio"
|
||||
|
||||
const REQUIRED = [
|
||||
{ value: "MAIN_PORT", default: "10000" },
|
||||
|
@ -19,7 +20,7 @@ const REQUIRED = [
|
|||
{ value: "MINIO_SECRET_KEY" },
|
||||
]
|
||||
|
||||
exports.checkURLs = config => {
|
||||
export function checkURLs(config: Record<string, string>) {
|
||||
const mainPort = config["MAIN_PORT"],
|
||||
username = config["COUCH_DB_USER"],
|
||||
password = config["COUCH_DB_PASSWORD"]
|
||||
|
@ -34,23 +35,23 @@ exports.checkURLs = config => {
|
|||
return config
|
||||
}
|
||||
|
||||
exports.askQuestions = async () => {
|
||||
export async function askQuestions() {
|
||||
console.log(
|
||||
"*** NOTE: use a .env file to load these parameters repeatedly ***"
|
||||
)
|
||||
let config = {}
|
||||
let config: Record<string, string> = {}
|
||||
for (let property of REQUIRED) {
|
||||
config[property.value] = await string(property.value, property.default)
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
exports.loadEnvironment = path => {
|
||||
export function loadEnvironment(path: string) {
|
||||
if (!fs.existsSync(path)) {
|
||||
throw "Unable to file specified .env file"
|
||||
}
|
||||
const env = fs.readFileSync(path, "utf8")
|
||||
const config = exports.checkURLs(dotenv.parse(env))
|
||||
const config = checkURLs(dotenv.parse(env))
|
||||
for (let required of REQUIRED) {
|
||||
if (!config[required.value]) {
|
||||
throw `Cannot find "${required.value}" property in .env file`
|
||||
|
@ -60,12 +61,12 @@ exports.loadEnvironment = path => {
|
|||
}
|
||||
|
||||
// true is the default value passed by commander
|
||||
exports.getConfig = async (envFile = true) => {
|
||||
export async function getConfig(envFile: boolean | string = true) {
|
||||
let config
|
||||
if (envFile !== true) {
|
||||
config = exports.loadEnvironment(envFile)
|
||||
config = loadEnvironment(envFile as string)
|
||||
} else {
|
||||
config = await exports.askQuestions()
|
||||
config = await askQuestions()
|
||||
}
|
||||
// fill out environment
|
||||
for (let key of Object.keys(config)) {
|
||||
|
@ -74,12 +75,16 @@ exports.getConfig = async (envFile = true) => {
|
|||
return config
|
||||
}
|
||||
|
||||
exports.replication = async (from, to) => {
|
||||
export async function replication(
|
||||
from: PouchDB.Database,
|
||||
to: PouchDB.Database
|
||||
) {
|
||||
const pouch = getPouch()
|
||||
try {
|
||||
await pouch.replicate(from, to, {
|
||||
batch_size: 1000,
|
||||
batch_limit: 5,
|
||||
batches_limit: 5,
|
||||
// @ts-ignore
|
||||
style: "main_only",
|
||||
})
|
||||
} catch (err) {
|
||||
|
@ -87,7 +92,7 @@ exports.replication = async (from, to) => {
|
|||
}
|
||||
}
|
||||
|
||||
exports.getPouches = config => {
|
||||
export function getPouches(config: Record<string, string>) {
|
||||
const Remote = getPouch(config["COUCH_DB_URL"])
|
||||
const Local = getPouch()
|
||||
return { Remote, Local }
|
|
@ -1,25 +0,0 @@
|
|||
const { Event } = require("@budibase/types")
|
||||
|
||||
exports.CommandWords = {
|
||||
BACKUPS: "backups",
|
||||
HOSTING: "hosting",
|
||||
ANALYTICS: "analytics",
|
||||
HELP: "help",
|
||||
PLUGIN: "plugins",
|
||||
}
|
||||
|
||||
exports.InitTypes = {
|
||||
QUICK: "quick",
|
||||
DIGITAL_OCEAN: "do",
|
||||
}
|
||||
|
||||
exports.AnalyticsEvents = {
|
||||
OptOut: "analytics:opt:out",
|
||||
OptIn: "analytics:opt:in",
|
||||
SelfHostInit: "hosting:init",
|
||||
PluginInit: Event.PLUGIN_INIT,
|
||||
}
|
||||
|
||||
exports.POSTHOG_TOKEN = "phc_yGOn4i7jWKaCTapdGR6lfA4AvmuEQ2ijn5zAVSFYPlS"
|
||||
|
||||
exports.GENERATED_USER_EMAIL = "admin@admin.com"
|
|
@ -0,0 +1,4 @@
|
|||
export { CommandWord, InitType, AnalyticsEvent } from "@budibase/types"
|
||||
|
||||
export const POSTHOG_TOKEN = "phc_yGOn4i7jWKaCTapdGR6lfA4AvmuEQ2ijn5zAVSFYPlS"
|
||||
export const GENERATED_USER_EMAIL = "admin@admin.com"
|
|
@ -1,12 +1,12 @@
|
|||
const PouchDB = require("pouchdb")
|
||||
const { checkSlashesInUrl } = require("../utils")
|
||||
const fetch = require("node-fetch")
|
||||
import PouchDB from "pouchdb"
|
||||
import { checkSlashesInUrl } from "../utils"
|
||||
import fetch from "node-fetch"
|
||||
|
||||
/**
|
||||
* Fully qualified URL including username and password, or nothing for local
|
||||
*/
|
||||
exports.getPouch = (url = undefined) => {
|
||||
let POUCH_DB_DEFAULTS = {}
|
||||
export function getPouch(url?: string) {
|
||||
let POUCH_DB_DEFAULTS
|
||||
if (!url) {
|
||||
POUCH_DB_DEFAULTS = {
|
||||
prefix: undefined,
|
||||
|
@ -19,11 +19,12 @@ exports.getPouch = (url = undefined) => {
|
|||
}
|
||||
const replicationStream = require("pouchdb-replication-stream")
|
||||
PouchDB.plugin(replicationStream.plugin)
|
||||
// @ts-ignore
|
||||
PouchDB.adapter("writableStream", replicationStream.adapters.writableStream)
|
||||
return PouchDB.defaults(POUCH_DB_DEFAULTS)
|
||||
return PouchDB.defaults(POUCH_DB_DEFAULTS) as PouchDB.Static
|
||||
}
|
||||
|
||||
exports.getAllDbs = async url => {
|
||||
export async function getAllDbs(url: string) {
|
||||
const response = await fetch(
|
||||
checkSlashesInUrl(encodeURI(`${url}/_all_dbs`)),
|
||||
{
|
|
@ -1,2 +1,3 @@
|
|||
process.env.NO_JS = "1"
|
||||
process.env.JS_BCRYPT = "1"
|
||||
process.env.DISABLE_JWT_WARNING = "1"
|
|
@ -1,11 +0,0 @@
|
|||
const AnalyticsClient = require("./analytics/Client")
|
||||
|
||||
const client = new AnalyticsClient()
|
||||
|
||||
exports.captureEvent = (event, properties) => {
|
||||
client.capture({
|
||||
distinctId: "cli",
|
||||
event,
|
||||
properties,
|
||||
})
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import { AnalyticsClient } from "./analytics/Client"
|
||||
|
||||
const client = new AnalyticsClient()
|
||||
|
||||
export function captureEvent(event: string, properties: any) {
|
||||
client.capture({
|
||||
distinctId: "cli",
|
||||
event,
|
||||
properties,
|
||||
})
|
||||
}
|
|
@ -1,21 +1,21 @@
|
|||
const util = require("util")
|
||||
const exec = util.promisify(require("child_process").exec)
|
||||
import util from "util"
|
||||
const runCommand = util.promisify(require("child_process").exec)
|
||||
|
||||
exports.exec = async (command, dir = "./") => {
|
||||
const { stdout } = await exec(command, { cwd: dir })
|
||||
export async function exec(command: string, dir = "./") {
|
||||
const { stdout } = await runCommand(command, { cwd: dir })
|
||||
return stdout
|
||||
}
|
||||
|
||||
exports.utilityInstalled = async utilName => {
|
||||
export async function utilityInstalled(utilName: string) {
|
||||
try {
|
||||
await exports.exec(`${utilName} --version`)
|
||||
await exec(`${utilName} --version`)
|
||||
return true
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
exports.runPkgCommand = async (command, dir = "./") => {
|
||||
export async function runPkgCommand(command: string, dir = "./") {
|
||||
const yarn = await exports.utilityInstalled("yarn")
|
||||
const npm = await exports.utilityInstalled("npm")
|
||||
if (!yarn && !npm) {
|
|
@ -2,15 +2,16 @@ const { success } = require("../utils")
|
|||
const { updateDockerComposeService } = require("./utils")
|
||||
const randomString = require("randomstring")
|
||||
const { GENERATED_USER_EMAIL } = require("../constants")
|
||||
import { DockerCompose } from "./types"
|
||||
|
||||
exports.generateUser = async (password, silent) => {
|
||||
export async function generateUser(password: string | null, silent: boolean) {
|
||||
const email = GENERATED_USER_EMAIL
|
||||
if (!password) {
|
||||
password = randomString.generate({ length: 6 })
|
||||
}
|
||||
updateDockerComposeService(service => {
|
||||
updateDockerComposeService((service: DockerCompose) => {
|
||||
service.environment["BB_ADMIN_USER_EMAIL"] = email
|
||||
service.environment["BB_ADMIN_USER_PASSWORD"] = password
|
||||
service.environment["BB_ADMIN_USER_PASSWORD"] = password as string
|
||||
})
|
||||
if (!silent) {
|
||||
console.log(
|
|
@ -1,14 +1,14 @@
|
|||
const Command = require("../structures/Command")
|
||||
const { CommandWords } = require("../constants")
|
||||
const { init } = require("./init")
|
||||
const { start } = require("./start")
|
||||
const { stop } = require("./stop")
|
||||
const { status } = require("./status")
|
||||
const { update } = require("./update")
|
||||
const { generateUser } = require("./genUser")
|
||||
const { watchPlugins } = require("./watch")
|
||||
import { Command } from "../structures/Command"
|
||||
import { CommandWord } from "../constants"
|
||||
import { init } from "./init"
|
||||
import { start } from "./start"
|
||||
import { stop } from "./stop"
|
||||
import { status } from "./status"
|
||||
import { update } from "./update"
|
||||
import { generateUser } from "./genUser"
|
||||
import { watchPlugins } from "./watch"
|
||||
|
||||
const command = new Command(`${CommandWords.HOSTING}`)
|
||||
export default new Command(`${CommandWord.HOSTING}`)
|
||||
.addHelp("Controls self hosting on the Budibase platform.")
|
||||
.addSubOption(
|
||||
"--init [type]",
|
||||
|
@ -46,5 +46,3 @@ const command = new Command(`${CommandWords.HOSTING}`)
|
|||
generateUser
|
||||
)
|
||||
.addSubOption("--single", "Specify this with init to use the single image.")
|
||||
|
||||
exports.command = command
|
|
@ -1,24 +1,25 @@
|
|||
const { InitTypes, AnalyticsEvents } = require("../constants")
|
||||
const { confirmation } = require("../questions")
|
||||
const { captureEvent } = require("../events")
|
||||
const makeFiles = require("./makeFiles")
|
||||
const axios = require("axios")
|
||||
const { parseEnv } = require("../utils")
|
||||
const { checkDockerConfigured, downloadFiles } = require("./utils")
|
||||
const { watchPlugins } = require("./watch")
|
||||
const { generateUser } = require("./genUser")
|
||||
import { InitType, AnalyticsEvent } from "../constants"
|
||||
import { confirmation } from "../questions"
|
||||
import { captureEvent } from "../events"
|
||||
import * as makeFiles from "./makeFiles"
|
||||
import { parseEnv } from "../utils"
|
||||
import { checkDockerConfigured, downloadDockerCompose } from "./utils"
|
||||
import { watchPlugins } from "./watch"
|
||||
import { generateUser } from "./genUser"
|
||||
import fetch from "node-fetch"
|
||||
|
||||
const DO_USER_DATA_URL = "http://169.254.169.254/metadata/v1/user-data"
|
||||
|
||||
async function getInitConfig(type, isQuick, port) {
|
||||
const config = isQuick ? makeFiles.QUICK_CONFIG : {}
|
||||
if (type === InitTypes.DIGITAL_OCEAN) {
|
||||
async function getInitConfig(type: string, isQuick: boolean, port: number) {
|
||||
const config: any = isQuick ? makeFiles.QUICK_CONFIG : {}
|
||||
if (type === InitType.DIGITAL_OCEAN) {
|
||||
try {
|
||||
const output = await axios.get(DO_USER_DATA_URL)
|
||||
const response = parseEnv(output.data)
|
||||
const output = await fetch(DO_USER_DATA_URL)
|
||||
const data = await output.text()
|
||||
const response = parseEnv(data)
|
||||
for (let [key, value] of Object.entries(makeFiles.ConfigMap)) {
|
||||
if (response[key]) {
|
||||
config[value] = response[key]
|
||||
config[value as string] = response[key]
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
|
@ -32,7 +33,7 @@ async function getInitConfig(type, isQuick, port) {
|
|||
return config
|
||||
}
|
||||
|
||||
exports.init = async opts => {
|
||||
export async function init(opts: any) {
|
||||
let type, isSingle, watchDir, genUser, port, silent
|
||||
if (typeof opts === "string") {
|
||||
type = opts
|
||||
|
@ -44,7 +45,7 @@ exports.init = async opts => {
|
|||
port = opts["port"]
|
||||
silent = opts["silent"]
|
||||
}
|
||||
const isQuick = type === InitTypes.QUICK || type === InitTypes.DIGITAL_OCEAN
|
||||
const isQuick = type === InitType.QUICK || type === InitType.DIGITAL_OCEAN
|
||||
await checkDockerConfigured()
|
||||
if (!isQuick) {
|
||||
const shouldContinue = await confirmation(
|
||||
|
@ -55,12 +56,12 @@ exports.init = async opts => {
|
|||
return
|
||||
}
|
||||
}
|
||||
captureEvent(AnalyticsEvents.SelfHostInit, {
|
||||
captureEvent(AnalyticsEvent.SelfHostInit, {
|
||||
type,
|
||||
})
|
||||
const config = await getInitConfig(type, isQuick, port)
|
||||
if (!isSingle) {
|
||||
await downloadFiles()
|
||||
await downloadDockerCompose()
|
||||
await makeFiles.makeEnv(config, silent)
|
||||
} else {
|
||||
await makeFiles.makeSingleCompose(config, silent)
|
|
@ -1,15 +1,15 @@
|
|||
const { number } = require("../questions")
|
||||
const { success, stringifyToDotEnv } = require("../utils")
|
||||
const fs = require("fs")
|
||||
const path = require("path")
|
||||
import { number } from "../questions"
|
||||
import { success, stringifyToDotEnv } from "../utils"
|
||||
import fs from "fs"
|
||||
import path from "path"
|
||||
import yaml from "yaml"
|
||||
import { getAppService } from "./utils"
|
||||
const randomString = require("randomstring")
|
||||
const yaml = require("yaml")
|
||||
const { getAppService } = require("./utils")
|
||||
|
||||
const SINGLE_IMAGE = "budibase/budibase:latest"
|
||||
const VOL_NAME = "budibase_data"
|
||||
const COMPOSE_PATH = path.resolve("./docker-compose.yaml")
|
||||
const ENV_PATH = path.resolve("./.env")
|
||||
export const COMPOSE_PATH = path.resolve("./docker-compose.yaml")
|
||||
export const ENV_PATH = path.resolve("./.env")
|
||||
|
||||
function getSecrets(opts = { single: false }) {
|
||||
const secrets = [
|
||||
|
@ -19,7 +19,7 @@ function getSecrets(opts = { single: false }) {
|
|||
"REDIS_PASSWORD",
|
||||
"INTERNAL_API_KEY",
|
||||
]
|
||||
const obj = {}
|
||||
const obj: Record<string, string> = {}
|
||||
secrets.forEach(secret => (obj[secret] = randomString.generate()))
|
||||
// setup couch creds separately
|
||||
if (opts && opts.single) {
|
||||
|
@ -32,7 +32,7 @@ function getSecrets(opts = { single: false }) {
|
|||
return obj
|
||||
}
|
||||
|
||||
function getSingleCompose(port) {
|
||||
function getSingleCompose(port: number) {
|
||||
const singleComposeObj = {
|
||||
version: "3",
|
||||
services: {
|
||||
|
@ -53,7 +53,7 @@ function getSingleCompose(port) {
|
|||
return yaml.stringify(singleComposeObj)
|
||||
}
|
||||
|
||||
function getEnv(port) {
|
||||
function getEnv(port: number) {
|
||||
const partOne = stringifyToDotEnv({
|
||||
MAIN_PORT: port,
|
||||
})
|
||||
|
@ -77,19 +77,21 @@ function getEnv(port) {
|
|||
].join("\n")
|
||||
}
|
||||
|
||||
exports.ENV_PATH = ENV_PATH
|
||||
exports.COMPOSE_PATH = COMPOSE_PATH
|
||||
|
||||
module.exports.ConfigMap = {
|
||||
export const ConfigMap = {
|
||||
MAIN_PORT: "port",
|
||||
}
|
||||
|
||||
module.exports.QUICK_CONFIG = {
|
||||
export const QUICK_CONFIG = {
|
||||
key: "budibase",
|
||||
port: 10000,
|
||||
}
|
||||
|
||||
async function make(path, contentsFn, inputs = {}, silent) {
|
||||
async function make(
|
||||
path: string,
|
||||
contentsFn: Function,
|
||||
inputs: any = {},
|
||||
silent: boolean
|
||||
) {
|
||||
const port =
|
||||
inputs.port ||
|
||||
(await number(
|
||||
|
@ -107,15 +109,15 @@ async function make(path, contentsFn, inputs = {}, silent) {
|
|||
}
|
||||
}
|
||||
|
||||
module.exports.makeEnv = async (inputs = {}, silent) => {
|
||||
export async function makeEnv(inputs: any = {}, silent: boolean) {
|
||||
return make(ENV_PATH, getEnv, inputs, silent)
|
||||
}
|
||||
|
||||
module.exports.makeSingleCompose = async (inputs = {}, silent) => {
|
||||
export async function makeSingleCompose(inputs: any = {}, silent: boolean) {
|
||||
return make(COMPOSE_PATH, getSingleCompose, inputs, silent)
|
||||
}
|
||||
|
||||
module.exports.getEnvProperty = property => {
|
||||
export function getEnvProperty(property: string) {
|
||||
const props = fs.readFileSync(ENV_PATH, "utf8").split(property)
|
||||
if (props[0].charAt(0) === "=") {
|
||||
property = props[0]
|
||||
|
@ -125,7 +127,7 @@ module.exports.getEnvProperty = property => {
|
|||
return property.split("=")[1].split("\n")[0]
|
||||
}
|
||||
|
||||
module.exports.getComposeProperty = property => {
|
||||
export function getComposeProperty(property: string) {
|
||||
const { service } = getAppService(COMPOSE_PATH)
|
||||
if (property === "port" && Array.isArray(service.ports)) {
|
||||
const port = service.ports[0]
|
|
@ -1,14 +1,10 @@
|
|||
const {
|
||||
checkDockerConfigured,
|
||||
checkInitComplete,
|
||||
handleError,
|
||||
} = require("./utils")
|
||||
const { info, success } = require("../utils")
|
||||
const makeFiles = require("./makeFiles")
|
||||
const compose = require("docker-compose")
|
||||
const fs = require("fs")
|
||||
import { checkDockerConfigured, checkInitComplete, handleError } from "./utils"
|
||||
import { info, success } from "../utils"
|
||||
import * as makeFiles from "./makeFiles"
|
||||
import compose from "docker-compose"
|
||||
import fs from "fs"
|
||||
|
||||
exports.start = async () => {
|
||||
export async function start() {
|
||||
await checkDockerConfigured()
|
||||
checkInitComplete()
|
||||
console.log(
|
|
@ -1,12 +1,8 @@
|
|||
const {
|
||||
checkDockerConfigured,
|
||||
checkInitComplete,
|
||||
handleError,
|
||||
} = require("./utils")
|
||||
const { info } = require("../utils")
|
||||
const compose = require("docker-compose")
|
||||
import { checkDockerConfigured, checkInitComplete, handleError } from "./utils"
|
||||
import { info } from "../utils"
|
||||
import compose from "docker-compose"
|
||||
|
||||
exports.status = async () => {
|
||||
export async function status() {
|
||||
await checkDockerConfigured()
|
||||
checkInitComplete()
|
||||
console.log(info("Budibase status"))
|
|
@ -1,12 +1,8 @@
|
|||
const {
|
||||
checkDockerConfigured,
|
||||
checkInitComplete,
|
||||
handleError,
|
||||
} = require("./utils")
|
||||
const { info, success } = require("../utils")
|
||||
const compose = require("docker-compose")
|
||||
import { checkDockerConfigured, checkInitComplete, handleError } from "./utils"
|
||||
import { info, success } from "../utils"
|
||||
import compose from "docker-compose"
|
||||
|
||||
exports.stop = async () => {
|
||||
export async function stop() {
|
||||
await checkDockerConfigured()
|
||||
checkInitComplete()
|
||||
console.log(info("Stopping services, this may take a moment."))
|
|
@ -0,0 +1,4 @@
|
|||
export interface DockerCompose {
|
||||
environment: Record<string, string>
|
||||
volumes: string[]
|
||||
}
|
|
@ -1,20 +1,20 @@
|
|||
const {
|
||||
import {
|
||||
checkDockerConfigured,
|
||||
checkInitComplete,
|
||||
downloadFiles,
|
||||
downloadDockerCompose,
|
||||
handleError,
|
||||
getServices,
|
||||
} = require("./utils")
|
||||
const { confirmation } = require("../questions")
|
||||
const compose = require("docker-compose")
|
||||
const { COMPOSE_PATH } = require("./makeFiles")
|
||||
const { info, success } = require("../utils")
|
||||
const { start } = require("./start")
|
||||
} from "./utils"
|
||||
import { confirmation } from "../questions"
|
||||
import compose from "docker-compose"
|
||||
import { COMPOSE_PATH } from "./makeFiles"
|
||||
import { info, success } from "../utils"
|
||||
import { start } from "./start"
|
||||
|
||||
const BB_COMPOSE_SERVICES = ["app-service", "worker-service", "proxy-service"]
|
||||
const BB_SINGLE_SERVICE = ["budibase"]
|
||||
|
||||
exports.update = async () => {
|
||||
export async function update() {
|
||||
const { services } = getServices(COMPOSE_PATH)
|
||||
const isSingle = Object.keys(services).length === 1
|
||||
await checkDockerConfigured()
|
||||
|
@ -23,7 +23,7 @@ exports.update = async () => {
|
|||
!isSingle &&
|
||||
(await confirmation("Do you wish to update you docker-compose.yaml?"))
|
||||
) {
|
||||
await downloadFiles()
|
||||
await downloadDockerCompose()
|
||||
}
|
||||
await handleError(async () => {
|
||||
const status = await compose.ps()
|
|
@ -1,24 +1,24 @@
|
|||
const { lookpath } = require("lookpath")
|
||||
const fs = require("fs")
|
||||
const makeFiles = require("./makeFiles")
|
||||
const { logErrorToFile, downloadFile, error } = require("../utils")
|
||||
const yaml = require("yaml")
|
||||
import { lookpath } from "lookpath"
|
||||
import fs from "fs"
|
||||
import * as makeFiles from "./makeFiles"
|
||||
import { logErrorToFile, downloadFile, error } from "../utils"
|
||||
import yaml from "yaml"
|
||||
import { DockerCompose } from "./types"
|
||||
|
||||
const ERROR_FILE = "docker-error.log"
|
||||
const FILE_URLS = [
|
||||
"https://raw.githubusercontent.com/Budibase/budibase/master/hosting/docker-compose.yaml",
|
||||
]
|
||||
const COMPOSE_URL =
|
||||
"https://raw.githubusercontent.com/Budibase/budibase/master/hosting/docker-compose.yaml"
|
||||
|
||||
exports.downloadFiles = async () => {
|
||||
const promises = []
|
||||
for (let url of FILE_URLS) {
|
||||
const fileName = url.split("/").slice(-1)[0]
|
||||
promises.push(downloadFile(url, `./${fileName}`))
|
||||
export async function downloadDockerCompose() {
|
||||
const fileName = COMPOSE_URL.split("/").slice(-1)[0]
|
||||
try {
|
||||
await downloadFile(COMPOSE_URL, `./${fileName}`)
|
||||
} catch (err) {
|
||||
console.error(error(`Failed to retrieve compose file - ${err}`))
|
||||
}
|
||||
await Promise.all(promises)
|
||||
}
|
||||
|
||||
exports.checkDockerConfigured = async () => {
|
||||
export async function checkDockerConfigured() {
|
||||
const error =
|
||||
"docker/docker-compose has not been installed, please follow instructions at: https://docs.budibase.com/docs/docker-compose"
|
||||
const docker = await lookpath("docker")
|
||||
|
@ -28,7 +28,7 @@ exports.checkDockerConfigured = async () => {
|
|||
}
|
||||
}
|
||||
|
||||
exports.checkInitComplete = () => {
|
||||
export function checkInitComplete() {
|
||||
if (
|
||||
!fs.existsSync(makeFiles.ENV_PATH) &&
|
||||
!fs.existsSync(makeFiles.COMPOSE_PATH)
|
||||
|
@ -37,10 +37,10 @@ exports.checkInitComplete = () => {
|
|||
}
|
||||
}
|
||||
|
||||
exports.handleError = async func => {
|
||||
export async function handleError(func: Function) {
|
||||
try {
|
||||
await func()
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (err && err.err) {
|
||||
logErrorToFile(ERROR_FILE, err.err)
|
||||
}
|
||||
|
@ -48,14 +48,14 @@ exports.handleError = async func => {
|
|||
}
|
||||
}
|
||||
|
||||
exports.getServices = path => {
|
||||
export function getServices(path: string) {
|
||||
const dockerYaml = fs.readFileSync(path, "utf8")
|
||||
const parsedYaml = yaml.parse(dockerYaml)
|
||||
return { yaml: parsedYaml, services: parsedYaml.services }
|
||||
}
|
||||
|
||||
exports.getAppService = path => {
|
||||
const { yaml, services } = exports.getServices(path),
|
||||
export function getAppService(path: string) {
|
||||
const { yaml, services } = getServices(path),
|
||||
serviceList = Object.keys(services)
|
||||
let service
|
||||
if (services["app-service"]) {
|
||||
|
@ -66,14 +66,17 @@ exports.getAppService = path => {
|
|||
return { yaml, service }
|
||||
}
|
||||
|
||||
exports.updateDockerComposeService = updateFn => {
|
||||
export function updateDockerComposeService(
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
updateFn: (service: DockerCompose) => void
|
||||
) {
|
||||
const opts = ["docker-compose.yaml", "docker-compose.yml"]
|
||||
const dockerFilePath = opts.find(name => fs.existsSync(name))
|
||||
if (!dockerFilePath) {
|
||||
console.log(error("Unable to locate docker-compose YAML."))
|
||||
return
|
||||
}
|
||||
const { yaml: parsedYaml, service } = exports.getAppService(dockerFilePath)
|
||||
const { yaml: parsedYaml, service } = getAppService(dockerFilePath)
|
||||
if (!service) {
|
||||
console.log(
|
||||
error(
|
|
@ -1,9 +1,10 @@
|
|||
const { resolve } = require("path")
|
||||
const fs = require("fs")
|
||||
const { error, success } = require("../utils")
|
||||
const { updateDockerComposeService } = require("./utils")
|
||||
import { resolve } from "path"
|
||||
import fs from "fs"
|
||||
import { error, success } from "../utils"
|
||||
import { updateDockerComposeService } from "./utils"
|
||||
import { DockerCompose } from "./types"
|
||||
|
||||
exports.watchPlugins = async (pluginPath, silent) => {
|
||||
export async function watchPlugins(pluginPath: string, silent: boolean) {
|
||||
const PLUGIN_PATH = "/plugins"
|
||||
// get absolute path
|
||||
pluginPath = resolve(pluginPath)
|
||||
|
@ -15,7 +16,7 @@ exports.watchPlugins = async (pluginPath, silent) => {
|
|||
)
|
||||
return
|
||||
}
|
||||
updateDockerComposeService(service => {
|
||||
updateDockerComposeService((service: DockerCompose) => {
|
||||
// set environment variable
|
||||
service.environment["PLUGINS_DIR"] = PLUGIN_PATH
|
||||
// add volumes to parsed yaml
|
|
@ -1,10 +1,10 @@
|
|||
#!/usr/bin/env node
|
||||
require("./prebuilds")
|
||||
require("./environment")
|
||||
import "./prebuilds"
|
||||
import "./environment"
|
||||
import { getCommands } from "./options"
|
||||
import { Command } from "commander"
|
||||
import { getHelpDescription } from "./utils"
|
||||
const json = require("../package.json")
|
||||
const { getCommands } = require("./options")
|
||||
const { Command } = require("commander")
|
||||
const { getHelpDescription } = require("./utils")
|
||||
|
||||
// add hosting config
|
||||
async function init() {
|
|
@ -1,8 +0,0 @@
|
|||
const analytics = require("./analytics")
|
||||
const hosting = require("./hosting")
|
||||
const backups = require("./backups")
|
||||
const plugins = require("./plugins")
|
||||
|
||||
exports.getCommands = () => {
|
||||
return [hosting.command, analytics.command, backups.command, plugins.command]
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
import analytics from "./analytics"
|
||||
import hosting from "./hosting"
|
||||
import backups from "./backups"
|
||||
import plugins from "./plugins"
|
||||
|
||||
export function getCommands() {
|
||||
return [hosting, analytics, backups, plugins]
|
||||
}
|
|
@ -1,18 +1,22 @@
|
|||
const Command = require("../structures/Command")
|
||||
const { CommandWords, AnalyticsEvents, InitTypes } = require("../constants")
|
||||
const { getSkeleton, fleshOutSkeleton } = require("./skeleton")
|
||||
const questions = require("../questions")
|
||||
const fs = require("fs")
|
||||
const { PLUGIN_TYPE_ARR } = require("@budibase/types")
|
||||
const { plugins } = require("@budibase/backend-core")
|
||||
const { runPkgCommand } = require("../exec")
|
||||
const { join } = require("path")
|
||||
const { success, error, info, moveDirectory } = require("../utils")
|
||||
const { captureEvent } = require("../events")
|
||||
import { Command } from "../structures/Command"
|
||||
import { CommandWord, AnalyticsEvent, InitType } from "../constants"
|
||||
import { getSkeleton, fleshOutSkeleton } from "./skeleton"
|
||||
import * as questions from "../questions"
|
||||
import fs from "fs"
|
||||
import { PluginType, PLUGIN_TYPE_ARR } from "@budibase/types"
|
||||
import { plugins } from "@budibase/backend-core"
|
||||
import { runPkgCommand } from "../exec"
|
||||
import { join } from "path"
|
||||
import { success, error, info, moveDirectory } from "../utils"
|
||||
import { captureEvent } from "../events"
|
||||
import { GENERATED_USER_EMAIL } from "../constants"
|
||||
import { init as hostingInit } from "../hosting/init"
|
||||
import { start as hostingStart } from "../hosting/start"
|
||||
const fp = require("find-free-port")
|
||||
const { GENERATED_USER_EMAIL } = require("../constants")
|
||||
const { init: hostingInit } = require("../hosting/init")
|
||||
const { start: hostingStart } = require("../hosting/start")
|
||||
|
||||
type PluginOpts = {
|
||||
init?: PluginType
|
||||
}
|
||||
|
||||
function checkInPlugin() {
|
||||
if (!fs.existsSync("package.json")) {
|
||||
|
@ -27,7 +31,7 @@ function checkInPlugin() {
|
|||
}
|
||||
}
|
||||
|
||||
async function askAboutTopLevel(name) {
|
||||
async function askAboutTopLevel(name: string) {
|
||||
const files = fs.readdirSync(process.cwd())
|
||||
// we are in an empty git repo, don't ask
|
||||
if (files.find(file => file === ".git")) {
|
||||
|
@ -45,8 +49,8 @@ async function askAboutTopLevel(name) {
|
|||
}
|
||||
}
|
||||
|
||||
async function init(opts) {
|
||||
const type = opts["init"] || opts
|
||||
async function init(opts: PluginOpts) {
|
||||
const type = opts["init"] || (opts as PluginType)
|
||||
if (!type || !PLUGIN_TYPE_ARR.includes(type)) {
|
||||
console.log(
|
||||
error(
|
||||
|
@ -82,7 +86,7 @@ async function init(opts) {
|
|||
} else {
|
||||
console.log(info(`Plugin created in directory "${name}"`))
|
||||
}
|
||||
captureEvent(AnalyticsEvents.PluginInit, {
|
||||
captureEvent(AnalyticsEvent.PluginInit, {
|
||||
type,
|
||||
name,
|
||||
description,
|
||||
|
@ -109,7 +113,7 @@ async function verify() {
|
|||
version = pkgJson.version
|
||||
plugins.validate(schemaJson)
|
||||
return { name, version }
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (err && err.message && err.message.includes("not valid JSON")) {
|
||||
console.log(error(`schema.json is not valid JSON: ${err.message}`))
|
||||
} else {
|
||||
|
@ -120,7 +124,7 @@ async function verify() {
|
|||
|
||||
async function build() {
|
||||
const verified = await verify()
|
||||
if (!verified.name) {
|
||||
if (!verified?.name) {
|
||||
return
|
||||
}
|
||||
console.log(success("Verified!"))
|
||||
|
@ -132,7 +136,7 @@ async function build() {
|
|||
|
||||
async function watch() {
|
||||
const verified = await verify()
|
||||
if (!verified.name) {
|
||||
if (!verified?.name) {
|
||||
return
|
||||
}
|
||||
const output = join("dist", `${verified.name}-${verified.version}.tar.gz`)
|
||||
|
@ -150,7 +154,7 @@ async function dev() {
|
|||
const [port] = await fp(10000)
|
||||
const password = "admin"
|
||||
await hostingInit({
|
||||
init: InitTypes.QUICK,
|
||||
init: InitType.QUICK,
|
||||
single: true,
|
||||
watchPluginDir: pluginDir,
|
||||
genUser: password,
|
||||
|
@ -168,7 +172,7 @@ async function dev() {
|
|||
console.log(success("Password: ") + info(password))
|
||||
}
|
||||
|
||||
const command = new Command(`${CommandWords.PLUGIN}`)
|
||||
export default new Command(`${CommandWord.PLUGIN}`)
|
||||
.addHelp(
|
||||
"Custom plugins for Budibase, init, build and verify your components and datasources with this tool."
|
||||
)
|
||||
|
@ -192,5 +196,3 @@ const command = new Command(`${CommandWords.PLUGIN}`)
|
|||
"Run a development environment which automatically watches the current directory.",
|
||||
dev
|
||||
)
|
||||
|
||||
exports.command = command
|
|
@ -1,21 +1,21 @@
|
|||
const fetch = require("node-fetch")
|
||||
import fetch from "node-fetch"
|
||||
import fs from "fs"
|
||||
import os from "os"
|
||||
import { join } from "path"
|
||||
import { processStringSync } from "@budibase/string-templates"
|
||||
const download = require("download")
|
||||
const fs = require("fs")
|
||||
const os = require("os")
|
||||
const { join } = require("path")
|
||||
const tar = require("tar")
|
||||
const { processStringSync } = require("@budibase/string-templates")
|
||||
|
||||
const HBS_FILES = ["package.json.hbs", "schema.json.hbs", "README.md.hbs"]
|
||||
|
||||
async function getSkeletonUrl(type) {
|
||||
async function getSkeletonUrl(type: string) {
|
||||
const resp = await fetch(
|
||||
"https://api.github.com/repos/budibase/budibase-skeleton/releases/latest"
|
||||
)
|
||||
if (resp.status >= 300) {
|
||||
throw new Error("Failed to retrieve skeleton metadata")
|
||||
}
|
||||
const json = await resp.json()
|
||||
const json = (await resp.json()) as { assets: any[] }
|
||||
for (let asset of json["assets"]) {
|
||||
if (asset.name && asset.name.includes(type)) {
|
||||
return asset["browser_download_url"]
|
||||
|
@ -24,7 +24,7 @@ async function getSkeletonUrl(type) {
|
|||
throw new Error("No skeleton found in latest release.")
|
||||
}
|
||||
|
||||
exports.getSkeleton = async (type, name) => {
|
||||
export async function getSkeleton(type: string, name: string) {
|
||||
const url = await getSkeletonUrl(type)
|
||||
const tarballFile = join(os.tmpdir(), "skeleton.tar.gz")
|
||||
|
||||
|
@ -40,7 +40,12 @@ exports.getSkeleton = async (type, name) => {
|
|||
fs.rmSync(tarballFile)
|
||||
}
|
||||
|
||||
exports.fleshOutSkeleton = async (type, name, description, version) => {
|
||||
export async function fleshOutSkeleton(
|
||||
type: string,
|
||||
name: string,
|
||||
description: string,
|
||||
version: string
|
||||
) {
|
||||
for (let file of HBS_FILES) {
|
||||
const oldFile = join(name, file),
|
||||
newFile = join(name, file.substring(0, file.length - 4))
|
|
@ -1,7 +1,8 @@
|
|||
const os = require("os")
|
||||
const { join } = require("path")
|
||||
const fs = require("fs")
|
||||
const { error } = require("./utils")
|
||||
import os from "os"
|
||||
import { join } from "path"
|
||||
import fs from "fs"
|
||||
import { error } from "./utils"
|
||||
|
||||
const PREBUILDS = "prebuilds"
|
||||
const ARCH = `${os.platform()}-${os.arch()}`
|
||||
const PREBUILD_DIR = join(process.execPath, "..", PREBUILDS, ARCH)
|
||||
|
@ -26,8 +27,8 @@ function checkForBinaries() {
|
|||
}
|
||||
}
|
||||
|
||||
function cleanup(evt) {
|
||||
if (!isNaN(evt)) {
|
||||
function cleanup(evt?: number) {
|
||||
if (evt && !isNaN(evt)) {
|
||||
return
|
||||
}
|
||||
if (evt) {
|
|
@ -1,6 +1,6 @@
|
|||
const inquirer = require("inquirer")
|
||||
|
||||
exports.confirmation = async question => {
|
||||
export async function confirmation(question: string) {
|
||||
const config = {
|
||||
type: "confirm",
|
||||
message: question,
|
||||
|
@ -10,8 +10,8 @@ exports.confirmation = async question => {
|
|||
return (await inquirer.prompt(config)).confirmation
|
||||
}
|
||||
|
||||
exports.string = async (question, defaultString = null) => {
|
||||
const config = {
|
||||
export async function string(question: string, defaultString?: string) {
|
||||
const config: any = {
|
||||
type: "input",
|
||||
name: "string",
|
||||
message: question,
|
||||
|
@ -22,12 +22,12 @@ exports.string = async (question, defaultString = null) => {
|
|||
return (await inquirer.prompt(config)).string
|
||||
}
|
||||
|
||||
exports.number = async (question, defaultNumber) => {
|
||||
const config = {
|
||||
export async function number(question: string, defaultNumber?: number) {
|
||||
const config: any = {
|
||||
type: "input",
|
||||
name: "number",
|
||||
message: question,
|
||||
validate: value => {
|
||||
validate: (value: string) => {
|
||||
let valid = !isNaN(parseFloat(value))
|
||||
return valid || "Please enter a number"
|
||||
},
|
|
@ -1,19 +1,31 @@
|
|||
const {
|
||||
import {
|
||||
getSubHelpDescription,
|
||||
getHelpDescription,
|
||||
error,
|
||||
capitaliseFirstLetter,
|
||||
} = require("../utils")
|
||||
} from "../utils"
|
||||
|
||||
class Command {
|
||||
constructor(command, func = null) {
|
||||
type CommandOpt = {
|
||||
command: string
|
||||
help: string
|
||||
func?: Function
|
||||
extras: any[]
|
||||
}
|
||||
|
||||
export class Command {
|
||||
command: string
|
||||
opts: CommandOpt[]
|
||||
func?: Function
|
||||
help?: string
|
||||
|
||||
constructor(command: string, func?: Function) {
|
||||
// if there are options, need to just get the command name
|
||||
this.command = command
|
||||
this.opts = []
|
||||
this.func = func
|
||||
}
|
||||
|
||||
convertToCommander(lookup) {
|
||||
convertToCommander(lookup: string) {
|
||||
const parts = lookup.toLowerCase().split("-")
|
||||
// camel case, separate out first
|
||||
const first = parts.shift()
|
||||
|
@ -22,21 +34,26 @@ class Command {
|
|||
.join("")
|
||||
}
|
||||
|
||||
addHelp(help) {
|
||||
addHelp(help: string) {
|
||||
this.help = help
|
||||
return this
|
||||
}
|
||||
|
||||
addSubOption(command, help, func, extras = []) {
|
||||
addSubOption(
|
||||
command: string,
|
||||
help: string,
|
||||
func?: Function,
|
||||
extras: any[] = []
|
||||
) {
|
||||
this.opts.push({ command, help, func, extras })
|
||||
return this
|
||||
}
|
||||
|
||||
configure(program) {
|
||||
configure(program: any) {
|
||||
const thisCmd = this
|
||||
let command = program.command(thisCmd.command)
|
||||
if (this.help) {
|
||||
command = command.description(getHelpDescription(thisCmd.help))
|
||||
command = command.description(getHelpDescription(thisCmd.help!))
|
||||
}
|
||||
for (let opt of thisCmd.opts) {
|
||||
command = command.option(opt.command, getSubHelpDescription(opt.help))
|
||||
|
@ -45,7 +62,7 @@ class Command {
|
|||
"--help",
|
||||
getSubHelpDescription(`Get help with ${this.command} options`)
|
||||
)
|
||||
command.action(async options => {
|
||||
command.action(async (options: Record<string, string>) => {
|
||||
try {
|
||||
let executed = false,
|
||||
found = false
|
||||
|
@ -53,7 +70,7 @@ class Command {
|
|||
let lookup = opt.command.split(" ")[0].replace("--", "")
|
||||
// need to handle how commander converts watch-plugin-dir to watchPluginDir
|
||||
lookup = this.convertToCommander(lookup)
|
||||
found = !executed && options[lookup]
|
||||
found = !executed && !!options[lookup]
|
||||
if (found && opt.func) {
|
||||
const input =
|
||||
Object.keys(options).length > 1 ? options : options[lookup]
|
||||
|
@ -69,11 +86,9 @@ class Command {
|
|||
console.log(error(`Unknown ${this.command} option.`))
|
||||
command.help()
|
||||
}
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
console.log(error(err))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Command
|
|
@ -3,7 +3,9 @@ const path = require("path")
|
|||
const os = require("os")
|
||||
const { error } = require("../utils")
|
||||
|
||||
class ConfigManager {
|
||||
export class ConfigManager {
|
||||
path: string
|
||||
|
||||
constructor() {
|
||||
this.path = path.join(os.homedir(), ".budibase.json")
|
||||
if (!fs.existsSync(this.path)) {
|
||||
|
@ -24,26 +26,24 @@ class ConfigManager {
|
|||
}
|
||||
}
|
||||
|
||||
set config(json) {
|
||||
set config(json: any) {
|
||||
fs.writeFileSync(this.path, JSON.stringify(json))
|
||||
}
|
||||
|
||||
getValue(key) {
|
||||
getValue(key: string) {
|
||||
return this.config[key]
|
||||
}
|
||||
|
||||
setValue(key, value) {
|
||||
setValue(key: string, value: any) {
|
||||
this.config = {
|
||||
...this.config,
|
||||
[key]: value,
|
||||
}
|
||||
}
|
||||
|
||||
removeKey(key) {
|
||||
removeKey(key: string) {
|
||||
const updated = { ...this.config }
|
||||
delete updated[key]
|
||||
this.config = updated
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ConfigManager
|
|
@ -1,106 +0,0 @@
|
|||
const chalk = require("chalk")
|
||||
const fs = require("fs")
|
||||
const axios = require("axios")
|
||||
const path = require("path")
|
||||
const progress = require("cli-progress")
|
||||
const { join } = require("path")
|
||||
|
||||
exports.downloadFile = async (url, filePath) => {
|
||||
filePath = path.resolve(filePath)
|
||||
const writer = fs.createWriteStream(filePath)
|
||||
|
||||
const response = await axios({
|
||||
url,
|
||||
method: "GET",
|
||||
responseType: "stream",
|
||||
})
|
||||
|
||||
response.data.pipe(writer)
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
writer.on("finish", resolve)
|
||||
writer.on("error", reject)
|
||||
})
|
||||
}
|
||||
|
||||
exports.httpCall = async (url, method) => {
|
||||
const response = await axios({
|
||||
url,
|
||||
method,
|
||||
})
|
||||
return response.data
|
||||
}
|
||||
|
||||
exports.getHelpDescription = string => {
|
||||
return chalk.cyan(string)
|
||||
}
|
||||
|
||||
exports.getSubHelpDescription = string => {
|
||||
return chalk.green(string)
|
||||
}
|
||||
|
||||
exports.error = error => {
|
||||
return chalk.red(`Error - ${error}`)
|
||||
}
|
||||
|
||||
exports.success = success => {
|
||||
return chalk.green(success)
|
||||
}
|
||||
|
||||
exports.info = info => {
|
||||
return chalk.cyan(info)
|
||||
}
|
||||
|
||||
exports.logErrorToFile = (file, error) => {
|
||||
fs.writeFileSync(path.resolve(`./${file}`), `Budibase Error\n${error}`)
|
||||
}
|
||||
|
||||
exports.parseEnv = env => {
|
||||
const lines = env.toString().split("\n")
|
||||
let result = {}
|
||||
for (const line of lines) {
|
||||
const match = line.match(/^([^=:#]+?)[=:](.*)/)
|
||||
if (match) {
|
||||
result[match[1].trim()] = match[2].trim()
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
exports.progressBar = total => {
|
||||
const bar = new progress.SingleBar({}, progress.Presets.shades_classic)
|
||||
bar.start(total, 0)
|
||||
return bar
|
||||
}
|
||||
|
||||
exports.checkSlashesInUrl = url => {
|
||||
return url.replace(/(https?:\/\/)|(\/)+/g, "$1$2")
|
||||
}
|
||||
|
||||
exports.moveDirectory = (oldPath, newPath) => {
|
||||
const files = fs.readdirSync(oldPath)
|
||||
// check any file exists already
|
||||
for (let file of files) {
|
||||
if (fs.existsSync(join(newPath, file))) {
|
||||
throw new Error(
|
||||
"Unable to remove top level directory - some skeleton files already exist."
|
||||
)
|
||||
}
|
||||
}
|
||||
for (let file of files) {
|
||||
fs.renameSync(join(oldPath, file), join(newPath, file))
|
||||
}
|
||||
fs.rmdirSync(oldPath)
|
||||
}
|
||||
|
||||
exports.capitaliseFirstLetter = str => {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||
}
|
||||
|
||||
exports.stringifyToDotEnv = json => {
|
||||
let str = ""
|
||||
for (let [key, value] of Object.entries(json)) {
|
||||
str += `${key}=${value}\n`
|
||||
}
|
||||
return str
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
import chalk from "chalk"
|
||||
import fs from "fs"
|
||||
import path from "path"
|
||||
import { join } from "path"
|
||||
import fetch from "node-fetch"
|
||||
const progress = require("cli-progress")
|
||||
|
||||
export function downloadFile(url: string, filePath: string) {
|
||||
return new Promise((resolve, reject) => {
|
||||
filePath = path.resolve(filePath)
|
||||
fetch(url, {
|
||||
method: "GET",
|
||||
})
|
||||
.then(response => {
|
||||
const writer = fs.createWriteStream(filePath)
|
||||
if (response.body) {
|
||||
response.body.pipe(writer)
|
||||
response.body.on("end", resolve)
|
||||
response.body.on("error", reject)
|
||||
} else {
|
||||
throw new Error(
|
||||
`Unable to retrieve docker-compose file - ${response.status}`
|
||||
)
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export async function httpCall(url: string, method: string) {
|
||||
const response = await fetch(url, {
|
||||
method,
|
||||
})
|
||||
return response.body
|
||||
}
|
||||
|
||||
export function getHelpDescription(str: string) {
|
||||
return chalk.cyan(str)
|
||||
}
|
||||
|
||||
export function getSubHelpDescription(str: string) {
|
||||
return chalk.green(str)
|
||||
}
|
||||
|
||||
export function error(err: string | number) {
|
||||
process.exitCode = -1
|
||||
return chalk.red(`Error - ${err}`)
|
||||
}
|
||||
|
||||
export function success(str: string) {
|
||||
return chalk.green(str)
|
||||
}
|
||||
|
||||
export function info(str: string) {
|
||||
return chalk.cyan(str)
|
||||
}
|
||||
|
||||
export function logErrorToFile(file: string, error: string) {
|
||||
fs.writeFileSync(path.resolve(`./${file}`), `Budibase Error\n${error}`)
|
||||
}
|
||||
|
||||
export function parseEnv(env: string) {
|
||||
const lines = env.toString().split("\n")
|
||||
let result: Record<string, string> = {}
|
||||
for (const line of lines) {
|
||||
const match = line.match(/^([^=:#]+?)[=:](.*)/)
|
||||
if (match) {
|
||||
result[match[1].trim()] = match[2].trim()
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export function progressBar(total: number) {
|
||||
const bar = new progress.SingleBar({}, progress.Presets.shades_classic)
|
||||
bar.start(total, 0)
|
||||
return bar
|
||||
}
|
||||
|
||||
export function checkSlashesInUrl(url: string) {
|
||||
return url.replace(/(https?:\/\/)|(\/)+/g, "$1$2")
|
||||
}
|
||||
|
||||
export function moveDirectory(oldPath: string, newPath: string) {
|
||||
const files = fs.readdirSync(oldPath)
|
||||
// check any file exists already
|
||||
for (let file of files) {
|
||||
if (fs.existsSync(join(newPath, file))) {
|
||||
throw new Error(
|
||||
"Unable to remove top level directory - some skeleton files already exist."
|
||||
)
|
||||
}
|
||||
}
|
||||
for (let file of files) {
|
||||
fs.renameSync(join(oldPath, file), join(newPath, file))
|
||||
}
|
||||
fs.rmdirSync(oldPath)
|
||||
}
|
||||
|
||||
export function capitaliseFirstLetter(str: string) {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||
}
|
||||
|
||||
export function stringifyToDotEnv(json: Record<string, string | number>) {
|
||||
let str = ""
|
||||
for (let [key, value] of Object.entries(json)) {
|
||||
str += `${key}=${value}\n`
|
||||
}
|
||||
return str
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
dir="$(dirname -- "$(readlink -f "${BASH_SOURCE}")")"
|
||||
${dir}/node_modules/ts-node/dist/bin.js ${dir}/src/index.ts $@
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"lib": ["es2020"],
|
||||
"strict": true,
|
||||
"noImplicitAny": true,
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
"incremental": true,
|
||||
"types": [ "node", "jest" ],
|
||||
"outDir": "dist",
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist",
|
||||
"**/*.spec.ts",
|
||||
"**/*.spec.js"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"extends": "./tsconfig.build.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@budibase/types": ["../types/src"],
|
||||
"@budibase/backend-core": ["../backend-core/src"],
|
||||
"@budibase/backend-core/*": ["../backend-core/*"],
|
||||
}
|
||||
},
|
||||
"ts-node": {
|
||||
"require": ["tsconfig-paths/register"],
|
||||
"swc": true
|
||||
},
|
||||
"references": [
|
||||
{ "path": "../types" },
|
||||
{ "path": "../backend-core" },
|
||||
],
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"package.json"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist"
|
||||
]
|
||||
}
|
|
@ -9,6 +9,13 @@
|
|||
dependencies:
|
||||
"@babel/highlight" "^7.10.4"
|
||||
|
||||
"@babel/code-frame@^7.12.13":
|
||||
version "7.18.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a"
|
||||
integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.18.6"
|
||||
|
||||
"@babel/generator@7.18.2":
|
||||
version "7.18.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.2.tgz#33873d6f89b21efe2da63fe554460f3df1c5880d"
|
||||
|
@ -33,7 +40,7 @@
|
|||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2"
|
||||
integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==
|
||||
|
||||
"@babel/highlight@^7.10.4":
|
||||
"@babel/highlight@^7.10.4", "@babel/highlight@^7.18.6":
|
||||
version "7.18.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf"
|
||||
integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==
|
||||
|
@ -71,6 +78,13 @@
|
|||
"@babel/helper-validator-identifier" "^7.19.1"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@cspotcode/source-map-support@^0.8.0":
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
|
||||
integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
|
||||
dependencies:
|
||||
"@jridgewell/trace-mapping" "0.3.9"
|
||||
|
||||
"@eslint/eslintrc@^0.4.3":
|
||||
version "0.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
|
||||
|
@ -112,6 +126,50 @@
|
|||
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
|
||||
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
|
||||
|
||||
"@jest/create-cache-key-function@^27.4.2":
|
||||
version "27.5.1"
|
||||
resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-27.5.1.tgz#7448fae15602ea95c828f5eceed35c202a820b31"
|
||||
integrity sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ==
|
||||
dependencies:
|
||||
"@jest/types" "^27.5.1"
|
||||
|
||||
"@jest/expect-utils@^29.4.3":
|
||||
version "29.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.4.3.tgz#95ce4df62952f071bcd618225ac7c47eaa81431e"
|
||||
integrity sha512-/6JWbkxHOP8EoS8jeeTd9dTfc9Uawi+43oLKHfp6zzux3U2hqOOVnV3ai4RpDYHOccL6g+5nrxpoc8DmJxtXVQ==
|
||||
dependencies:
|
||||
jest-get-type "^29.4.3"
|
||||
|
||||
"@jest/schemas@^29.4.3":
|
||||
version "29.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.3.tgz#39cf1b8469afc40b6f5a2baaa146e332c4151788"
|
||||
integrity sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==
|
||||
dependencies:
|
||||
"@sinclair/typebox" "^0.25.16"
|
||||
|
||||
"@jest/types@^27.5.1":
|
||||
version "27.5.1"
|
||||
resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80"
|
||||
integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==
|
||||
dependencies:
|
||||
"@types/istanbul-lib-coverage" "^2.0.0"
|
||||
"@types/istanbul-reports" "^3.0.0"
|
||||
"@types/node" "*"
|
||||
"@types/yargs" "^16.0.0"
|
||||
chalk "^4.0.0"
|
||||
|
||||
"@jest/types@^29.4.3":
|
||||
version "29.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.4.3.tgz#9069145f4ef09adf10cec1b2901b2d390031431f"
|
||||
integrity sha512-bPYfw8V65v17m2Od1cv44FH+SiKW7w2Xu7trhcdTLUmSv85rfKsP+qXSjO4KGJr4dtPSzl/gvslZBXctf1qGEA==
|
||||
dependencies:
|
||||
"@jest/schemas" "^29.4.3"
|
||||
"@types/istanbul-lib-coverage" "^2.0.0"
|
||||
"@types/istanbul-reports" "^3.0.0"
|
||||
"@types/node" "*"
|
||||
"@types/yargs" "^17.0.8"
|
||||
chalk "^4.0.0"
|
||||
|
||||
"@jridgewell/gen-mapping@^0.3.0":
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9"
|
||||
|
@ -121,7 +179,7 @@
|
|||
"@jridgewell/sourcemap-codec" "^1.4.10"
|
||||
"@jridgewell/trace-mapping" "^0.3.9"
|
||||
|
||||
"@jridgewell/resolve-uri@3.1.0":
|
||||
"@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
|
||||
integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
|
||||
|
@ -136,6 +194,14 @@
|
|||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
|
||||
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
|
||||
|
||||
"@jridgewell/trace-mapping@0.3.9":
|
||||
version "0.3.9"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
|
||||
integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
|
||||
dependencies:
|
||||
"@jridgewell/resolve-uri" "^3.0.3"
|
||||
"@jridgewell/sourcemap-codec" "^1.4.10"
|
||||
|
||||
"@jridgewell/trace-mapping@^0.3.9":
|
||||
version "0.3.17"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985"
|
||||
|
@ -182,11 +248,332 @@
|
|||
resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df"
|
||||
integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==
|
||||
|
||||
"@sinclair/typebox@^0.25.16":
|
||||
version "0.25.24"
|
||||
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718"
|
||||
integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==
|
||||
|
||||
"@sindresorhus/is@^0.7.0":
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd"
|
||||
integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==
|
||||
|
||||
"@swc/core-darwin-arm64@1.3.37":
|
||||
version "1.3.37"
|
||||
resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.37.tgz#a92e075ae35f18a64aaf3823ea175f03564f8da1"
|
||||
integrity sha512-iIyVqqioUpVeT/hbBVfkrsjfCyL4idNH+LVKGmoTAWaTTSB0+UNhNuA7Wh2CqIHWh1Mv7IlumitWPcqsVDdoEw==
|
||||
|
||||
"@swc/core-darwin-x64@1.3.37":
|
||||
version "1.3.37"
|
||||
resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.37.tgz#a3cc06c87140a2ca0b8e7ef1f3d5cc34dd080429"
|
||||
integrity sha512-dao5nXPWKxtaxqak4ZkRyBoApNIelW/glantQhPhj0FjMjuIQc+v03ldJ8XDByWOG+6xuVUTheANCtEccxoQBw==
|
||||
|
||||
"@swc/core-linux-arm-gnueabihf@1.3.37":
|
||||
version "1.3.37"
|
||||
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.37.tgz#f7d8f8523830c6be653f608839d4bd5598457f1f"
|
||||
integrity sha512-/mVrc8H/f062CUkqKGmBiil2VIYu4mKawHxERfeP1y38X5K/OwjG5s9MgO9TVxy+Ly6vejwj70kRhSa3hVp1Bw==
|
||||
|
||||
"@swc/core-linux-arm64-gnu@1.3.37":
|
||||
version "1.3.37"
|
||||
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.37.tgz#b162febd9de14fb08000c722b063be2bb5aefa6b"
|
||||
integrity sha512-eRQ3KaZI0j5LidTfOIi/kUVOOMuVmw1HCdt/Z1TAUKoHMLVxY8xcJ3pEE3/+ednI60EmHpwpJRs6LelXyL6uzQ==
|
||||
|
||||
"@swc/core-linux-arm64-musl@1.3.37":
|
||||
version "1.3.37"
|
||||
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.37.tgz#3b1a628e880fbb1a5e2a7a46d42e8aa878c6bfdd"
|
||||
integrity sha512-w2BRLODyxNQY2rfHZMZ5ir6QrrnGBPlnIslTrgKmVbn1OjZoxUCtuqhrYnCmybaAc4DOkeH02TqynEFXrm+EMw==
|
||||
|
||||
"@swc/core-linux-x64-gnu@1.3.37":
|
||||
version "1.3.37"
|
||||
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.37.tgz#ed443ad77dc90e415267d02a38e4113047b2d3d8"
|
||||
integrity sha512-CfoH8EsZJZ9kunjMUjBNYD5fFuO86zw+K/o4wEw72Yg6ZEiqPmeIlCKU8tpTv4sK+CbhUXrmVzMB5tqsb2jALQ==
|
||||
|
||||
"@swc/core-linux-x64-musl@1.3.37":
|
||||
version "1.3.37"
|
||||
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.37.tgz#de607a4985458bd6e8b0e40f0d62d0e26bd8df1e"
|
||||
integrity sha512-9YPrHYNdoG7PK11gV51GfL45biI2dic+YTqHUDKyykemsD7Ot1zUFX7Ty//pdvpKcKSff6SrHbfFACD5ziNirA==
|
||||
|
||||
"@swc/core-win32-arm64-msvc@1.3.37":
|
||||
version "1.3.37"
|
||||
resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.37.tgz#d5851a47d7df183929b9746d56f76c282f940e6a"
|
||||
integrity sha512-h17Ek8/wCDje6BrXOvCXBM80oBRmTSMMdLyt87whTl5xqYlWYYs9oQIzZndNRTlNpTgjGO8Ns2eo4kwVxIkBIA==
|
||||
|
||||
"@swc/core-win32-ia32-msvc@1.3.37":
|
||||
version "1.3.37"
|
||||
resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.37.tgz#06ad7016f61b56aec4abf60eab3a91b786f9e294"
|
||||
integrity sha512-1BR175E1olGy/zdt94cgdb6ps/lBNissAOaxyBk8taFpcjy3zpdP30yAoH0GIsC6isnZ5JfArbOJNRXXO5tE0Q==
|
||||
|
||||
"@swc/core-win32-x64-msvc@1.3.37":
|
||||
version "1.3.37"
|
||||
resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.37.tgz#60139a7089003a7447a4efef9704ae8fde21995e"
|
||||
integrity sha512-1siDQ7dccQ1pesJmgAL3BUBbRPtfbNInOWnZOkiie/DfFqGQ117QKnCVyjUvwFKfTQx1+3UUTDmMSlRd00SlXg==
|
||||
|
||||
"@swc/core@^1.3.25":
|
||||
version "1.3.37"
|
||||
resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.3.37.tgz#644653fa7deb20c7c342e7fd019c7abc44ecf1bf"
|
||||
integrity sha512-VOFlEQ1pReOM73N9A7R8rt561GU8Rxsq833jiimWDUB2sXEN3V6n6wFTgYmZuMz2T4/R0cQA1nV48KkaT4gkFw==
|
||||
optionalDependencies:
|
||||
"@swc/core-darwin-arm64" "1.3.37"
|
||||
"@swc/core-darwin-x64" "1.3.37"
|
||||
"@swc/core-linux-arm-gnueabihf" "1.3.37"
|
||||
"@swc/core-linux-arm64-gnu" "1.3.37"
|
||||
"@swc/core-linux-arm64-musl" "1.3.37"
|
||||
"@swc/core-linux-x64-gnu" "1.3.37"
|
||||
"@swc/core-linux-x64-musl" "1.3.37"
|
||||
"@swc/core-win32-arm64-msvc" "1.3.37"
|
||||
"@swc/core-win32-ia32-msvc" "1.3.37"
|
||||
"@swc/core-win32-x64-msvc" "1.3.37"
|
||||
|
||||
"@swc/jest@^0.2.24":
|
||||
version "0.2.24"
|
||||
resolved "https://registry.yarnpkg.com/@swc/jest/-/jest-0.2.24.tgz#35d9377ede049613cd5fdd6c24af2b8dcf622875"
|
||||
integrity sha512-fwgxQbM1wXzyKzl1+IW0aGrRvAA8k0Y3NxFhKigbPjOJ4mCKnWEcNX9HQS3gshflcxq8YKhadabGUVfdwjCr6Q==
|
||||
dependencies:
|
||||
"@jest/create-cache-key-function" "^27.4.2"
|
||||
jsonc-parser "^3.2.0"
|
||||
|
||||
"@tsconfig/node10@^1.0.7":
|
||||
version "1.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2"
|
||||
integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==
|
||||
|
||||
"@tsconfig/node12@^1.0.7":
|
||||
version "1.0.11"
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d"
|
||||
integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==
|
||||
|
||||
"@tsconfig/node14@^1.0.0":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1"
|
||||
integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==
|
||||
|
||||
"@tsconfig/node16@^1.0.2":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e"
|
||||
integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==
|
||||
|
||||
"@types/debug@*":
|
||||
version "4.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82"
|
||||
integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==
|
||||
dependencies:
|
||||
"@types/ms" "*"
|
||||
|
||||
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44"
|
||||
integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==
|
||||
|
||||
"@types/istanbul-lib-report@*":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686"
|
||||
integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==
|
||||
dependencies:
|
||||
"@types/istanbul-lib-coverage" "*"
|
||||
|
||||
"@types/istanbul-reports@^3.0.0":
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff"
|
||||
integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==
|
||||
dependencies:
|
||||
"@types/istanbul-lib-report" "*"
|
||||
|
||||
"@types/jest@^29.4.0":
|
||||
version "29.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.4.0.tgz#a8444ad1704493e84dbf07bb05990b275b3b9206"
|
||||
integrity sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ==
|
||||
dependencies:
|
||||
expect "^29.0.0"
|
||||
pretty-format "^29.0.0"
|
||||
|
||||
"@types/ms@*":
|
||||
version "0.7.31"
|
||||
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197"
|
||||
integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==
|
||||
|
||||
"@types/node-fetch@2.6.1":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.1.tgz#8f127c50481db65886800ef496f20bbf15518975"
|
||||
integrity sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
form-data "^3.0.0"
|
||||
|
||||
"@types/node@*":
|
||||
version "18.14.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.14.4.tgz#0e64ec0b35a772e1e3d849f9a0ff61782d0cb647"
|
||||
integrity sha512-VhCw7I7qO2X49+jaKcAUwi3rR+hbxT5VcYF493+Z5kMLI0DL568b7JI4IDJaxWFH0D/xwmGJNoXisyX+w7GH/g==
|
||||
|
||||
"@types/pouchdb-adapter-cordova-sqlite@*":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/pouchdb-adapter-cordova-sqlite/-/pouchdb-adapter-cordova-sqlite-1.0.1.tgz#49e5ee6df7cc0c23196fcb340f43a560e74eb1d6"
|
||||
integrity sha512-nqlXpW1ho3KBg1mUQvZgH2755y3z/rw4UA7ZJCPMRTHofxGMY8izRVw5rHBL4/7P615or0J2udpRYxgkT3D02g==
|
||||
dependencies:
|
||||
"@types/pouchdb-core" "*"
|
||||
|
||||
"@types/pouchdb-adapter-fruitdown@*":
|
||||
version "6.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/pouchdb-adapter-fruitdown/-/pouchdb-adapter-fruitdown-6.1.3.tgz#9b140ad9645cc56068728acf08ec19ac0046658e"
|
||||
integrity sha512-Wz1Z1JLOW1hgmFQjqnSkmyyfH7by/iWb4abKn684WMvQfmxx6BxKJpJ4+eulkVPQzzgMMSgU1MpnQOm9FgRkbw==
|
||||
dependencies:
|
||||
"@types/pouchdb-core" "*"
|
||||
|
||||
"@types/pouchdb-adapter-http@*":
|
||||
version "6.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/pouchdb-adapter-http/-/pouchdb-adapter-http-6.1.3.tgz#6e592d5f48deb6274a21ddac1498dd308096bcf3"
|
||||
integrity sha512-9Z4TLbF/KJWy/D2sWRPBA+RNU0odQimfdvlDX+EY7rGcd3aVoH8qjD/X0Xcd/0dfBH5pKrNIMFFQgW/TylRCmA==
|
||||
dependencies:
|
||||
"@types/pouchdb-core" "*"
|
||||
|
||||
"@types/pouchdb-adapter-idb@*":
|
||||
version "6.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/pouchdb-adapter-idb/-/pouchdb-adapter-idb-6.1.4.tgz#cb9a18864585d600820cd325f007614c5c3989cd"
|
||||
integrity sha512-KIAXbkF4uYUz0ZwfNEFLtEkK44mEWopAsD76UhucH92XnJloBysav+TjI4FFfYQyTjoW3S1s6V+Z14CUJZ0F6w==
|
||||
dependencies:
|
||||
"@types/pouchdb-core" "*"
|
||||
|
||||
"@types/pouchdb-adapter-leveldb@*":
|
||||
version "6.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/pouchdb-adapter-leveldb/-/pouchdb-adapter-leveldb-6.1.3.tgz#17c7e75d75b992050bca15991e97fba575c61bb3"
|
||||
integrity sha512-ex8NFqQGFwEpFi7AaZ5YofmuemfZNsL3nTFZBUCAKYMBkazQij1pe2ILLStSvJr0XS0qxgXjCEW19T5Wqiiskg==
|
||||
dependencies:
|
||||
"@types/pouchdb-core" "*"
|
||||
|
||||
"@types/pouchdb-adapter-localstorage@*":
|
||||
version "6.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/pouchdb-adapter-localstorage/-/pouchdb-adapter-localstorage-6.1.3.tgz#0dde02ba6b9d6073a295a20196563942ba9a54bd"
|
||||
integrity sha512-oor040tye1KKiGLWYtIy7rRT7C2yoyX3Tf6elEJRpjOA7Ja/H8lKc4LaSh9ATbptIcES6MRqZDxtp7ly9hsW3Q==
|
||||
dependencies:
|
||||
"@types/pouchdb-core" "*"
|
||||
|
||||
"@types/pouchdb-adapter-memory@*":
|
||||
version "6.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/pouchdb-adapter-memory/-/pouchdb-adapter-memory-6.1.3.tgz#9eabdbc890fcf58960ee8b68b8685f837e75c844"
|
||||
integrity sha512-gVbsIMzDzgZYThFVT4eVNsmuZwVm/4jDxP1sjlgc3qtDIxbtBhGgyNfcskwwz9Zu5Lv1avkDsIWvcxQhnvRlHg==
|
||||
dependencies:
|
||||
"@types/pouchdb-core" "*"
|
||||
|
||||
"@types/pouchdb-adapter-node-websql@*":
|
||||
version "6.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/pouchdb-adapter-node-websql/-/pouchdb-adapter-node-websql-6.1.3.tgz#aa18bc68af8cf509acd12c400010dcd5fab2243d"
|
||||
integrity sha512-F/P+os6Jsa7CgHtH64+Z0HfwIcj0hIRB5z8gNhF7L7dxPWoAfkopK5H2gydrP3sQrlGyN4WInF+UJW/Zu1+FKg==
|
||||
dependencies:
|
||||
"@types/pouchdb-adapter-websql" "*"
|
||||
"@types/pouchdb-core" "*"
|
||||
|
||||
"@types/pouchdb-adapter-websql@*":
|
||||
version "6.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/pouchdb-adapter-websql/-/pouchdb-adapter-websql-6.1.4.tgz#359fbe42ccac0ac90b492ddb8c32fafd0aa96d79"
|
||||
integrity sha512-zMJQCtXC40hBsIDRn0GhmpeGMK0f9l/OGWfLguvczROzxxcOD7REI+e6SEmX7gJKw5JuMvlfuHzkQwjmvSJbtg==
|
||||
dependencies:
|
||||
"@types/pouchdb-core" "*"
|
||||
|
||||
"@types/pouchdb-browser@*":
|
||||
version "6.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/pouchdb-browser/-/pouchdb-browser-6.1.3.tgz#8f33d6ef58d6817d1f6d36979148a1c7f63244d8"
|
||||
integrity sha512-EdYowrWxW9SWBMX/rux2eq7dbHi5Zeyzz+FF/IAsgQKnUxgeCO5VO2j4zTzos0SDyJvAQU+EYRc11r7xGn5tvA==
|
||||
dependencies:
|
||||
"@types/pouchdb-adapter-http" "*"
|
||||
"@types/pouchdb-adapter-idb" "*"
|
||||
"@types/pouchdb-adapter-websql" "*"
|
||||
"@types/pouchdb-core" "*"
|
||||
"@types/pouchdb-mapreduce" "*"
|
||||
"@types/pouchdb-replication" "*"
|
||||
|
||||
"@types/pouchdb-core@*":
|
||||
version "7.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/pouchdb-core/-/pouchdb-core-7.0.10.tgz#d1ea1549e7fad6cb579f71459b1bc27252e06a5a"
|
||||
integrity sha512-mKhjLlWWXyV3PTTjDhzDV1kc2dolO7VYFa75IoKM/hr8Er9eo8RIbS7mJLfC8r/C3p6ihZu9yZs1PWC1LQ0SOA==
|
||||
dependencies:
|
||||
"@types/debug" "*"
|
||||
"@types/pouchdb-find" "*"
|
||||
|
||||
"@types/pouchdb-find@*":
|
||||
version "7.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/pouchdb-find/-/pouchdb-find-7.3.0.tgz#b917030e9f4bf6e56bf8c3b9fe4b2a25e989009a"
|
||||
integrity sha512-sFPli5tBjGX9UfXioik1jUzPdcN84eV82n0lmEFuoPepWqkLjQcyri0eOa++HYOaNPyMDhKFBqEALEZivK2dRg==
|
||||
dependencies:
|
||||
"@types/pouchdb-core" "*"
|
||||
|
||||
"@types/pouchdb-http@*":
|
||||
version "6.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/pouchdb-http/-/pouchdb-http-6.1.3.tgz#09576c0d409da1f8dee34ec5b768415e2472ea52"
|
||||
integrity sha512-0e9E5SqNOyPl/3FnEIbENssB4FlJsNYuOy131nxrZk36S+y1R/6qO7ZVRypWpGTqBWSuVd7gCsq2UDwO/285+w==
|
||||
dependencies:
|
||||
"@types/pouchdb-adapter-http" "*"
|
||||
"@types/pouchdb-core" "*"
|
||||
|
||||
"@types/pouchdb-mapreduce@*":
|
||||
version "6.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/pouchdb-mapreduce/-/pouchdb-mapreduce-6.1.7.tgz#9ab32d1e0f234f1bf6d1e4c5d7e216e9e23ac0a3"
|
||||
integrity sha512-WzBwm7tmO9QhfRzVaWT4v6JQSS/fG2OoUDrWrhX87rPe2Pn6laPvdK5li6myNRxCoI/l5e8Jd+oYBAFnaiFucA==
|
||||
dependencies:
|
||||
"@types/pouchdb-core" "*"
|
||||
|
||||
"@types/pouchdb-node@*":
|
||||
version "6.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/pouchdb-node/-/pouchdb-node-6.1.4.tgz#5214c0169fcfd2237d373380bbd65a934feb5dfb"
|
||||
integrity sha512-wnTCH8X1JOPpNOfVhz8HW0AvmdHh6pt40MuRj0jQnK7QEHsHS79WujsKTKSOF8QXtPwpvCNSsI7ut7H7tfxxJQ==
|
||||
dependencies:
|
||||
"@types/pouchdb-adapter-http" "*"
|
||||
"@types/pouchdb-adapter-leveldb" "*"
|
||||
"@types/pouchdb-core" "*"
|
||||
"@types/pouchdb-mapreduce" "*"
|
||||
"@types/pouchdb-replication" "*"
|
||||
|
||||
"@types/pouchdb-replication@*":
|
||||
version "6.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/pouchdb-replication/-/pouchdb-replication-6.4.4.tgz#743406c90f13a988fa3e346ea74ce40acd170d00"
|
||||
integrity sha512-BsE5LKpjJK4iAf6Fx5kyrMw+33V+Ip7uWldUnU2BYrrvtR+MLD22dcImm7DZN1st2wPPb91i0XEnQzvP0w1C/Q==
|
||||
dependencies:
|
||||
"@types/pouchdb-core" "*"
|
||||
"@types/pouchdb-find" "*"
|
||||
|
||||
"@types/pouchdb@^6.4.0":
|
||||
version "6.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/pouchdb/-/pouchdb-6.4.0.tgz#f9c41ca64b23029f9bf2eb4bf6956e6431cb79f8"
|
||||
integrity sha512-eGCpX+NXhd5VLJuJMzwe3L79fa9+IDTrAG3CPaf4s/31PD56hOrhDJTSmRELSXuiqXr6+OHzzP0PldSaWsFt7w==
|
||||
dependencies:
|
||||
"@types/pouchdb-adapter-cordova-sqlite" "*"
|
||||
"@types/pouchdb-adapter-fruitdown" "*"
|
||||
"@types/pouchdb-adapter-http" "*"
|
||||
"@types/pouchdb-adapter-idb" "*"
|
||||
"@types/pouchdb-adapter-leveldb" "*"
|
||||
"@types/pouchdb-adapter-localstorage" "*"
|
||||
"@types/pouchdb-adapter-memory" "*"
|
||||
"@types/pouchdb-adapter-node-websql" "*"
|
||||
"@types/pouchdb-adapter-websql" "*"
|
||||
"@types/pouchdb-browser" "*"
|
||||
"@types/pouchdb-core" "*"
|
||||
"@types/pouchdb-http" "*"
|
||||
"@types/pouchdb-mapreduce" "*"
|
||||
"@types/pouchdb-node" "*"
|
||||
"@types/pouchdb-replication" "*"
|
||||
|
||||
"@types/stack-utils@^2.0.0":
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
|
||||
integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==
|
||||
|
||||
"@types/yargs-parser@*":
|
||||
version "21.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b"
|
||||
integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==
|
||||
|
||||
"@types/yargs@^16.0.0":
|
||||
version "16.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.5.tgz#12cc86393985735a283e387936398c2f9e5f88e3"
|
||||
integrity sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ==
|
||||
dependencies:
|
||||
"@types/yargs-parser" "*"
|
||||
|
||||
"@types/yargs@^17.0.8":
|
||||
version "17.0.22"
|
||||
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.22.tgz#7dd37697691b5f17d020f3c63e7a45971ff71e9a"
|
||||
integrity sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==
|
||||
dependencies:
|
||||
"@types/yargs-parser" "*"
|
||||
|
||||
abort-controller@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
|
||||
|
@ -221,11 +608,21 @@ acorn-jsx@^5.3.1:
|
|||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
||||
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
|
||||
|
||||
acorn-walk@^8.1.1:
|
||||
version "8.2.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
|
||||
integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
|
||||
|
||||
acorn@^7.4.0:
|
||||
version "7.4.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
||||
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
||||
|
||||
acorn@^8.4.1:
|
||||
version "8.8.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a"
|
||||
integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==
|
||||
|
||||
agent-base@6:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
|
||||
|
@ -289,6 +686,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
|
|||
dependencies:
|
||||
color-convert "^2.0.1"
|
||||
|
||||
ansi-styles@^5.0.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
|
||||
integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
|
||||
|
||||
aproba@^1.0.3:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
|
||||
|
@ -309,6 +711,11 @@ are-we-there-yet@~1.1.2:
|
|||
delegates "^1.0.0"
|
||||
readable-stream "^2.0.6"
|
||||
|
||||
arg@^4.1.0:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
|
||||
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
|
||||
|
||||
argparse@^1.0.7:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
|
||||
|
@ -351,6 +758,11 @@ astral-regex@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
|
||||
integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
|
||||
|
||||
at-least-node@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
|
||||
|
@ -519,6 +931,11 @@ chownr@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
|
||||
integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
|
||||
|
||||
ci-info@^3.2.0:
|
||||
version "3.8.0"
|
||||
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91"
|
||||
integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==
|
||||
|
||||
cli-cursor@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307"
|
||||
|
@ -588,6 +1005,13 @@ color-name@~1.1.4:
|
|||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
combined-stream@^1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
command-line-args@^5.2.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e"
|
||||
|
@ -658,6 +1082,11 @@ core-util-is@~1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
|
||||
integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
|
||||
|
||||
create-require@^1.1.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
|
||||
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
|
||||
|
||||
cross-spawn@^7.0.2:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||
|
@ -774,6 +1203,11 @@ deferred-leveldown@~5.3.0:
|
|||
abstract-leveldown "~6.2.1"
|
||||
inherits "^2.0.3"
|
||||
|
||||
delayed-stream@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
|
||||
|
||||
delegates@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
|
||||
|
@ -784,6 +1218,16 @@ detect-libc@^1.0.3:
|
|||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
|
||||
integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==
|
||||
|
||||
diff-sequences@^29.4.3:
|
||||
version "29.4.3"
|
||||
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2"
|
||||
integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==
|
||||
|
||||
diff@^4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
|
||||
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
||||
|
||||
dir-glob@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
|
||||
|
@ -791,10 +1235,12 @@ dir-glob@^3.0.1:
|
|||
dependencies:
|
||||
path-type "^4.0.0"
|
||||
|
||||
docker-compose@0.23.6:
|
||||
version "0.23.6"
|
||||
resolved "https://registry.yarnpkg.com/docker-compose/-/docker-compose-0.23.6.tgz#bd21e17d599f17fcf7a4b5d607cff0358a9c378b"
|
||||
integrity sha512-y3Q8MkwG862rNqkvEQG59/7Fi2/fzs3NYDCvqUAAD+z0WGs2qcJ9hRcn34hWgWv9ouPkFqe3Vwca0h+4bIIRWw==
|
||||
docker-compose@0.23.12:
|
||||
version "0.23.12"
|
||||
resolved "https://registry.yarnpkg.com/docker-compose/-/docker-compose-0.23.12.tgz#fa883b98be08f6926143d06bf9e522ef7ed3210c"
|
||||
integrity sha512-KFbSMqQBuHjTGZGmYDOCO0L4SaML3BsWTId5oSUyaBa22vALuFHNv+UdDWs3HcMylHWKsxCbLB7hnM/nCosWZw==
|
||||
dependencies:
|
||||
yaml "^1.10.2"
|
||||
|
||||
doctrine@^3.0.0:
|
||||
version "3.0.0"
|
||||
|
@ -888,6 +1334,11 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
|
|||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
|
||||
|
||||
escape-string-regexp@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344"
|
||||
integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
|
||||
|
||||
escape-string-regexp@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
||||
|
@ -1017,6 +1468,17 @@ expand-template@^2.0.3:
|
|||
resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c"
|
||||
integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==
|
||||
|
||||
expect@^29.0.0:
|
||||
version "29.4.3"
|
||||
resolved "https://registry.yarnpkg.com/expect/-/expect-29.4.3.tgz#5e47757316df744fe3b8926c3ae8a3ebdafff7fe"
|
||||
integrity sha512-uC05+Q7eXECFpgDrHdXA4k2rpMyStAYPItEDLyQDo5Ta7fVkJnNA/4zh/OIVkVVNZ1oOK1PipQoyNjuZ6sz6Dg==
|
||||
dependencies:
|
||||
"@jest/expect-utils" "^29.4.3"
|
||||
jest-get-type "^29.4.3"
|
||||
jest-matcher-utils "^29.4.3"
|
||||
jest-message-util "^29.4.3"
|
||||
jest-util "^29.4.3"
|
||||
|
||||
ext-list@^2.0.0:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37"
|
||||
|
@ -1191,6 +1653,15 @@ follow-redirects@^1.14.0:
|
|||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5"
|
||||
integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==
|
||||
|
||||
form-data@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f"
|
||||
integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.8"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
from2@^2.1.1, from2@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
|
||||
|
@ -1348,7 +1819,7 @@ got@^8.3.1:
|
|||
url-parse-lax "^3.0.0"
|
||||
url-to-options "^1.0.1"
|
||||
|
||||
graceful-fs@^4.1.10, graceful-fs@^4.1.6, graceful-fs@^4.2.0:
|
||||
graceful-fs@^4.1.10, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.9:
|
||||
version "4.2.10"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
|
||||
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
|
||||
|
@ -1604,6 +2075,58 @@ isurl@^1.0.0-alpha5:
|
|||
has-to-string-tag-x "^1.2.0"
|
||||
is-object "^1.0.1"
|
||||
|
||||
jest-diff@^29.4.3:
|
||||
version "29.4.3"
|
||||
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.4.3.tgz#42f4eb34d0bf8c0fb08b0501069b87e8e84df347"
|
||||
integrity sha512-YB+ocenx7FZ3T5O9lMVMeLYV4265socJKtkwgk/6YUz/VsEzYDkiMuMhWzZmxm3wDRQvayJu/PjkjjSkjoHsCA==
|
||||
dependencies:
|
||||
chalk "^4.0.0"
|
||||
diff-sequences "^29.4.3"
|
||||
jest-get-type "^29.4.3"
|
||||
pretty-format "^29.4.3"
|
||||
|
||||
jest-get-type@^29.4.3:
|
||||
version "29.4.3"
|
||||
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5"
|
||||
integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==
|
||||
|
||||
jest-matcher-utils@^29.4.3:
|
||||
version "29.4.3"
|
||||
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.4.3.tgz#ea68ebc0568aebea4c4213b99f169ff786df96a0"
|
||||
integrity sha512-TTciiXEONycZ03h6R6pYiZlSkvYgT0l8aa49z/DLSGYjex4orMUcafuLXYyyEDWB1RKglq00jzwY00Ei7yFNVg==
|
||||
dependencies:
|
||||
chalk "^4.0.0"
|
||||
jest-diff "^29.4.3"
|
||||
jest-get-type "^29.4.3"
|
||||
pretty-format "^29.4.3"
|
||||
|
||||
jest-message-util@^29.4.3:
|
||||
version "29.4.3"
|
||||
resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.4.3.tgz#65b5280c0fdc9419503b49d4f48d4999d481cb5b"
|
||||
integrity sha512-1Y8Zd4ZCN7o/QnWdMmT76If8LuDv23Z1DRovBj/vcSFNlGCJGoO8D1nJDw1AdyAGUk0myDLFGN5RbNeJyCRGCw==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.12.13"
|
||||
"@jest/types" "^29.4.3"
|
||||
"@types/stack-utils" "^2.0.0"
|
||||
chalk "^4.0.0"
|
||||
graceful-fs "^4.2.9"
|
||||
micromatch "^4.0.4"
|
||||
pretty-format "^29.4.3"
|
||||
slash "^3.0.0"
|
||||
stack-utils "^2.0.3"
|
||||
|
||||
jest-util@^29.4.3:
|
||||
version "29.4.3"
|
||||
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.4.3.tgz#851a148e23fc2b633c55f6dad2e45d7f4579f496"
|
||||
integrity sha512-ToSGORAz4SSSoqxDSylWX8JzkOQR7zoBtNRsA7e+1WUX5F8jrOwaNpuh1YfJHJKDHXLHmObv5eOjejUd+/Ws+Q==
|
||||
dependencies:
|
||||
"@jest/types" "^29.4.3"
|
||||
"@types/node" "*"
|
||||
chalk "^4.0.0"
|
||||
ci-info "^3.2.0"
|
||||
graceful-fs "^4.2.9"
|
||||
picomatch "^2.2.3"
|
||||
|
||||
joi@17.6.0:
|
||||
version "17.6.0"
|
||||
resolved "https://registry.yarnpkg.com/joi/-/joi-17.6.0.tgz#0bb54f2f006c09a96e75ce687957bd04290054b2"
|
||||
|
@ -1663,6 +2186,11 @@ json-stringify-safe@^5.0.1:
|
|||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
|
||||
|
||||
jsonc-parser@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76"
|
||||
integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==
|
||||
|
||||
jsonfile@^6.0.1:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
|
||||
|
@ -1857,6 +2385,11 @@ make-dir@^2.1.0:
|
|||
pify "^4.0.1"
|
||||
semver "^5.6.0"
|
||||
|
||||
make-error@^1.1.1:
|
||||
version "1.3.6"
|
||||
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
|
||||
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
|
||||
|
||||
md5@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f"
|
||||
|
@ -1879,11 +2412,18 @@ micromatch@^4.0.4:
|
|||
braces "^3.0.2"
|
||||
picomatch "^2.3.1"
|
||||
|
||||
mime-db@^1.28.0:
|
||||
mime-db@1.52.0, mime-db@^1.28.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:
|
||||
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==
|
||||
dependencies:
|
||||
mime-db "1.52.0"
|
||||
|
||||
mimic-fn@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
|
||||
|
@ -1991,7 +2531,7 @@ node-abi@^2.21.0:
|
|||
dependencies:
|
||||
semver "^5.4.1"
|
||||
|
||||
node-fetch@2, node-fetch@2.6.7, node-fetch@^2.6.6:
|
||||
node-fetch@2.6.7, node-fetch@^2.6.6:
|
||||
version "2.6.7"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
|
||||
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
|
||||
|
@ -2137,7 +2677,7 @@ pend@~1.2.0:
|
|||
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
|
||||
integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
|
||||
|
||||
picomatch@^2.3.1:
|
||||
picomatch@^2.2.3, picomatch@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
||||
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
|
||||
|
@ -2300,6 +2840,15 @@ prepend-http@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
|
||||
integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==
|
||||
|
||||
pretty-format@^29.0.0, pretty-format@^29.4.3:
|
||||
version "29.4.3"
|
||||
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.4.3.tgz#25500ada21a53c9e8423205cf0337056b201244c"
|
||||
integrity sha512-cvpcHTc42lcsvOOAzd3XuNWTcvk1Jmnzqeu+WsOuiPmxUJTnkbAcFNsRKvEpBEUFVUgy/GTZLulZDcDEi+CIlA==
|
||||
dependencies:
|
||||
"@jest/schemas" "^29.4.3"
|
||||
ansi-styles "^5.0.0"
|
||||
react-is "^18.0.0"
|
||||
|
||||
printj@^1.3.0:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/printj/-/printj-1.3.1.tgz#9af6b1d55647a1587ac44f4c1654a4b95b8e12cb"
|
||||
|
@ -2374,6 +2923,11 @@ rc@^1.2.7:
|
|||
minimist "^1.2.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
|
||||
react-is@^18.0.0:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
|
||||
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
|
||||
|
||||
readable-stream@1.1.14, readable-stream@^1.0.27-1:
|
||||
version "1.1.14"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
|
||||
|
@ -2656,6 +3210,13 @@ sprintf-js@~1.0.2:
|
|||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
|
||||
|
||||
stack-utils@^2.0.3:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f"
|
||||
integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==
|
||||
dependencies:
|
||||
escape-string-regexp "^2.0.0"
|
||||
|
||||
stream-meter@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/stream-meter/-/stream-meter-1.0.4.tgz#52af95aa5ea760a2491716704dbff90f73afdd1d"
|
||||
|
@ -2911,6 +3472,25 @@ trim-repeated@^1.0.0:
|
|||
dependencies:
|
||||
escape-string-regexp "^1.0.2"
|
||||
|
||||
ts-node@^10.9.1:
|
||||
version "10.9.1"
|
||||
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b"
|
||||
integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==
|
||||
dependencies:
|
||||
"@cspotcode/source-map-support" "^0.8.0"
|
||||
"@tsconfig/node10" "^1.0.7"
|
||||
"@tsconfig/node12" "^1.0.7"
|
||||
"@tsconfig/node14" "^1.0.0"
|
||||
"@tsconfig/node16" "^1.0.2"
|
||||
acorn "^8.4.1"
|
||||
acorn-walk "^8.1.1"
|
||||
arg "^4.1.0"
|
||||
create-require "^1.1.0"
|
||||
diff "^4.0.1"
|
||||
make-error "^1.1.1"
|
||||
v8-compile-cache-lib "^3.0.1"
|
||||
yn "3.1.1"
|
||||
|
||||
tslib@^1.9.0:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
|
@ -2940,6 +3520,11 @@ type-fest@^0.21.3:
|
|||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
|
||||
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
|
||||
|
||||
typescript@4.7.3:
|
||||
version "4.7.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.3.tgz#8364b502d5257b540f9de4c40be84c98e23a129d"
|
||||
integrity sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==
|
||||
|
||||
typical@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4"
|
||||
|
@ -3015,6 +3600,11 @@ uuid@8.3.2, uuid@^8.3.2:
|
|||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
|
||||
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
||||
|
||||
v8-compile-cache-lib@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
|
||||
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
|
||||
|
||||
v8-compile-cache@^2.0.3:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
||||
|
@ -3101,6 +3691,11 @@ yallist@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
|
||||
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
||||
|
||||
yaml@^1.10.2:
|
||||
version "1.10.2"
|
||||
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
|
||||
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
|
||||
|
||||
yaml@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.1.1.tgz#1e06fb4ca46e60d9da07e4f786ea370ed3c3cfec"
|
||||
|
@ -3131,3 +3726,8 @@ yauzl@^2.4.2:
|
|||
dependencies:
|
||||
buffer-crc32 "~0.2.3"
|
||||
fd-slicer "~1.1.0"
|
||||
|
||||
yn@3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
|
||||
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/client",
|
||||
"version": "2.3.18-alpha.29",
|
||||
"version": "2.4.8-alpha.4",
|
||||
"license": "MPL-2.0",
|
||||
"module": "dist/budibase-client.js",
|
||||
"main": "dist/budibase-client.js",
|
||||
|
@ -19,9 +19,11 @@
|
|||
"dev:builder": "rollup -cw"
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "2.3.18-alpha.29",
|
||||
"@budibase/frontend-core": "2.3.18-alpha.29",
|
||||
"@budibase/string-templates": "2.3.18-alpha.29",
|
||||
"@budibase/bbui": "2.4.8-alpha.4",
|
||||
"@budibase/frontend-core": "2.4.8-alpha.4",
|
||||
"@budibase/shared-core": "2.4.8-alpha.4",
|
||||
"@budibase/string-templates": "2.4.8-alpha.4",
|
||||
"@budibase/types": "2.4.8-alpha.4",
|
||||
"@spectrum-css/button": "^3.0.3",
|
||||
"@spectrum-css/card": "^3.0.3",
|
||||
"@spectrum-css/divider": "^1.0.3",
|
||||
|
|
|
@ -20,6 +20,19 @@ const ignoredWarnings = [
|
|||
"a11y-click-events-have-key-events",
|
||||
]
|
||||
|
||||
const devPaths = production
|
||||
? []
|
||||
: [
|
||||
{
|
||||
find: "@budibase/shared-core",
|
||||
replacement: path.resolve("../shared-core/dist/mjs/src/index"),
|
||||
},
|
||||
{
|
||||
find: "@budibase/types",
|
||||
replacement: path.resolve("../types/dist/mjs/index"),
|
||||
},
|
||||
]
|
||||
|
||||
export default {
|
||||
input: "src/index.js",
|
||||
output: [
|
||||
|
@ -69,6 +82,7 @@ export default {
|
|||
find: "sdk",
|
||||
replacement: path.resolve("./src/sdk"),
|
||||
},
|
||||
...devPaths,
|
||||
],
|
||||
}),
|
||||
svelte({
|
||||
|
|
|
@ -57,6 +57,9 @@
|
|||
const onFieldChange = (expression, field) => {
|
||||
// Update the field type
|
||||
expression.type = schemaFields.find(x => x.name === field)?.type
|
||||
expression.externalType = schemaFields.find(
|
||||
x => x.name === field
|
||||
)?.externalType
|
||||
|
||||
// Ensure a valid operator is set
|
||||
const validOperators = LuceneUtils.getValidOperatorsForType(
|
||||
|
|
|
@ -283,27 +283,32 @@
|
|||
if (mapInstance) {
|
||||
mapInstance.remove()
|
||||
}
|
||||
mapInstance = L.map(embeddedMapId, mapOptions)
|
||||
mapMarkerGroup.addTo(mapInstance)
|
||||
candidateMarkerGroup.addTo(mapInstance)
|
||||
|
||||
// Add attribution
|
||||
const cleanAttribution = sanitizeHtml(attribution, {
|
||||
allowedTags: ["a"],
|
||||
allowedAttributes: {
|
||||
a: ["href", "target"],
|
||||
},
|
||||
})
|
||||
L.tileLayer(tileURL, {
|
||||
attribution: "© " + cleanAttribution,
|
||||
zoom,
|
||||
}).addTo(mapInstance)
|
||||
try {
|
||||
mapInstance = L.map(embeddedMapId, mapOptions)
|
||||
mapMarkerGroup.addTo(mapInstance)
|
||||
candidateMarkerGroup.addTo(mapInstance)
|
||||
|
||||
// Add click handler
|
||||
mapInstance.on("click", handleMapClick)
|
||||
// Add attribution
|
||||
const cleanAttribution = sanitizeHtml(attribution, {
|
||||
allowedTags: ["a"],
|
||||
allowedAttributes: {
|
||||
a: ["href", "target"],
|
||||
},
|
||||
})
|
||||
L.tileLayer(tileURL, {
|
||||
attribution: "© " + cleanAttribution,
|
||||
zoom,
|
||||
}).addTo(mapInstance)
|
||||
|
||||
// Reset view
|
||||
resetView()
|
||||
// Add click handler
|
||||
mapInstance.on("click", handleMapClick)
|
||||
|
||||
// Reset view
|
||||
resetView()
|
||||
} catch (e) {
|
||||
console.log("There was a problem with the map", e)
|
||||
}
|
||||
}
|
||||
|
||||
const handleMapClick = e => {
|
||||
|
|
|
@ -81,6 +81,7 @@ export const getRelationshipSchemaAdditions = async schema => {
|
|||
Object.keys(linkSchema || {}).forEach(linkKey => {
|
||||
relationshipAdditions[`${fieldKey}.${linkKey}`] = {
|
||||
type: linkSchema[linkKey].type,
|
||||
externalType: linkSchema[linkKey].externalType,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
{
|
||||
"name": "@budibase/frontend-core",
|
||||
"version": "2.3.18-alpha.29",
|
||||
"version": "2.4.8-alpha.4",
|
||||
"description": "Budibase frontend core libraries used in builder and client",
|
||||
"author": "Budibase",
|
||||
"license": "MPL-2.0",
|
||||
"svelte": "src/index.js",
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "2.3.18-alpha.29",
|
||||
"@budibase/bbui": "2.4.8-alpha.4",
|
||||
"@budibase/shared-core": "2.4.8-alpha.4",
|
||||
"lodash": "^4.17.21",
|
||||
"svelte": "^3.46.2"
|
||||
}
|
||||
|
|
|
@ -194,8 +194,7 @@ export const buildUserEndpoints = API => ({
|
|||
},
|
||||
|
||||
/**
|
||||
* Retrieves the invitation associated with a provided code.
|
||||
* @param code The unique code for the target invite
|
||||
* Retrieves all user invitations for the current tenant.
|
||||
*/
|
||||
getUserInvites: async () => {
|
||||
return await API.get({
|
||||
|
|
|
@ -1,56 +1,7 @@
|
|||
/**
|
||||
* Operator options for lucene queries
|
||||
*/
|
||||
export const OperatorOptions = {
|
||||
Equals: {
|
||||
value: "equal",
|
||||
label: "Equals",
|
||||
},
|
||||
NotEquals: {
|
||||
value: "notEqual",
|
||||
label: "Not equals",
|
||||
},
|
||||
Empty: {
|
||||
value: "empty",
|
||||
label: "Is empty",
|
||||
},
|
||||
NotEmpty: {
|
||||
value: "notEmpty",
|
||||
label: "Is not empty",
|
||||
},
|
||||
StartsWith: {
|
||||
value: "string",
|
||||
label: "Starts with",
|
||||
},
|
||||
Like: {
|
||||
value: "fuzzy",
|
||||
label: "Like",
|
||||
},
|
||||
MoreThan: {
|
||||
value: "rangeLow",
|
||||
label: "More than or equal to",
|
||||
},
|
||||
LessThan: {
|
||||
value: "rangeHigh",
|
||||
label: "Less than or equal to",
|
||||
},
|
||||
Contains: {
|
||||
value: "contains",
|
||||
label: "Contains",
|
||||
},
|
||||
NotContains: {
|
||||
value: "notContains",
|
||||
label: "Does not contain",
|
||||
},
|
||||
In: {
|
||||
value: "oneOf",
|
||||
label: "Is in",
|
||||
},
|
||||
ContainsAny: {
|
||||
value: "containsAny",
|
||||
label: "Has any",
|
||||
},
|
||||
}
|
||||
export { OperatorOptions, SqlNumberTypeRangeMap } from "@budibase/shared-core"
|
||||
|
||||
// Cookie names
|
||||
export const Cookies = {
|
||||
|
@ -127,27 +78,6 @@ export const Roles = {
|
|||
PUBLIC: "PUBLIC",
|
||||
BUILDER: "BUILDER",
|
||||
}
|
||||
/**
|
||||
* Maximum minimum range for SQL number values
|
||||
*/
|
||||
export const SqlNumberTypeRangeMap = {
|
||||
integer: {
|
||||
max: 2147483647,
|
||||
min: -2147483648,
|
||||
},
|
||||
int: {
|
||||
max: 2147483647,
|
||||
min: -2147483648,
|
||||
},
|
||||
smallint: {
|
||||
max: 32767,
|
||||
min: -32768,
|
||||
},
|
||||
mediumint: {
|
||||
max: 8388607,
|
||||
min: -8388608,
|
||||
},
|
||||
}
|
||||
|
||||
export const Themes = [
|
||||
{
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
import { writable, derived, get } from "svelte/store"
|
||||
import { cloneDeep } from "lodash/fp"
|
||||
import {
|
||||
buildLuceneQuery,
|
||||
luceneLimit,
|
||||
runLuceneQuery,
|
||||
luceneSort,
|
||||
} from "../utils/lucene"
|
||||
import { LuceneUtils } from "../utils"
|
||||
import { convertJSONSchemaToTableSchema } from "../utils/json"
|
||||
|
||||
const { buildLuceneQuery, luceneLimit, runLuceneQuery, luceneSort } =
|
||||
LuceneUtils
|
||||
|
||||
/**
|
||||
* Parent class which handles the implementation of fetching data from an
|
||||
* internal table or datasource plus.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export * as LuceneUtils from "./lucene"
|
||||
export { dataFilters as LuceneUtils } from "@budibase/shared-core"
|
||||
export * as JSONUtils from "./json"
|
||||
export * as CookieUtils from "./cookies"
|
||||
export * as RoleUtils from "./roles"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@budibase/sdk",
|
||||
"version": "2.3.18-alpha.29",
|
||||
"version": "2.4.8-alpha.4",
|
||||
"description": "Budibase Public API SDK",
|
||||
"author": "Budibase",
|
||||
"license": "MPL-2.0",
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue