Merge branch 'develop' into BUDI-7367/ds_plus_row_unittest
This commit is contained in:
commit
e2b8226de1
|
@ -7,7 +7,4 @@ packages/worker/coverage
|
||||||
packages/backend-core/coverage
|
packages/backend-core/coverage
|
||||||
packages/server/client
|
packages/server/client
|
||||||
packages/builder/.routify
|
packages/builder/.routify
|
||||||
packages/builder/cypress/support/queryLevelTransformerFunction.js
|
|
||||||
packages/builder/cypress/support/queryLevelTransformerFunctionWithData.js
|
|
||||||
packages/builder/cypress/reports
|
|
||||||
packages/sdk/sdk
|
packages/sdk/sdk
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
# Budibase CI Pipelines
|
# Budibase CI Pipelines
|
||||||
|
|
||||||
Welcome to the budibase CI pipelines directory. This document details what each of the CI pipelines are for, and come common combinations.
|
Welcome to the budibase CI pipelines directory. This document details what each of the CI pipelines are for, and come common combinations.
|
||||||
|
@ -6,27 +5,34 @@ Welcome to the budibase CI pipelines directory. This document details what each
|
||||||
## All CI Pipelines
|
## All CI Pipelines
|
||||||
|
|
||||||
### Note
|
### Note
|
||||||
- When running workflow dispatch jobs, ensure you always run them off the `master` branch. It defaults to `develop`, so double check before running any jobs. The exception to this case is the `deploy-release` job which requires the develop branch.
|
|
||||||
|
- When running workflow dispatch jobs, ensure you always run them off the `master` branch. It defaults to `develop`, so double check before running any jobs. The exception to this case is the `deploy-release` job which requires the develop branch.
|
||||||
|
|
||||||
### Standard CI Build Job (budibase_ci.yml)
|
### Standard CI Build Job (budibase_ci.yml)
|
||||||
|
|
||||||
Triggers:
|
Triggers:
|
||||||
|
|
||||||
- PR or push to develop
|
- PR or push to develop
|
||||||
- PR or push to master
|
- PR or push to master
|
||||||
|
|
||||||
The standard CI Build job is what runs when you raise a PR to develop or master.
|
The standard CI Build job is what runs when you raise a PR to develop or master.
|
||||||
|
|
||||||
- Installs all dependencies,
|
- Installs all dependencies,
|
||||||
- builds the project
|
- builds the project
|
||||||
- run the unit tests
|
- run the unit tests
|
||||||
- Generate test coverage metrics with codecov
|
- Generate test coverage metrics with codecov
|
||||||
- Run the cypress tests
|
- Run the integration tests
|
||||||
|
|
||||||
### Release Develop Job (release-develop.yml)
|
### Release Develop Job (release-develop.yml)
|
||||||
|
|
||||||
Triggers:
|
Triggers:
|
||||||
|
|
||||||
- Push to develop
|
- Push to develop
|
||||||
|
|
||||||
The job responsible for building, tagging and pushing docker images out to the test and release environments.
|
The job responsible for building, tagging and pushing docker images out to the test and release environments.
|
||||||
|
|
||||||
- Installs all dependencies
|
- Installs all dependencies
|
||||||
- builds the project
|
- builds the project
|
||||||
- run the unit tests
|
- run the unit tests
|
||||||
- publish the budibase JS packages under a prerelease tag to NPM
|
- publish the budibase JS packages under a prerelease tag to NPM
|
||||||
- build, tag and push docker images under the `develop` tag to docker hub
|
- build, tag and push docker images under the `develop` tag to docker hub
|
||||||
|
@ -34,23 +40,29 @@ The job responsible for building, tagging and pushing docker images out to the t
|
||||||
These images will then be pulled by the test and release environments, updating the latest automatically. Discord notifications are sent to the #infra channel when this occurs.
|
These images will then be pulled by the test and release environments, updating the latest automatically. Discord notifications are sent to the #infra channel when this occurs.
|
||||||
|
|
||||||
### Release Job (release.yml)
|
### Release Job (release.yml)
|
||||||
|
|
||||||
Triggers:
|
Triggers:
|
||||||
|
|
||||||
- Push to master
|
- Push to master
|
||||||
|
|
||||||
This job is responsible for building and pushing the latest code to NPM and docker hub, so that it can be deployed.
|
This job is responsible for building and pushing the latest code to NPM and docker hub, so that it can be deployed.
|
||||||
|
|
||||||
- Installs all dependencies
|
- Installs all dependencies
|
||||||
- builds the project
|
- builds the project
|
||||||
- run the unit tests
|
- run the unit tests
|
||||||
- publish the budibase JS packages under a release tag to NPM (always incremented by patch versions)
|
- publish the budibase JS packages under a release tag to NPM (always incremented by patch versions)
|
||||||
- build, tag and push docker images under the `v.x.x.x` (the tag of the NPM release) tag to docker hub
|
- build, tag and push docker images under the `v.x.x.x` (the tag of the NPM release) tag to docker hub
|
||||||
|
|
||||||
### Release Selfhost Job (release-selfhost.yml)
|
### Release Selfhost Job (release-selfhost.yml)
|
||||||
|
|
||||||
Triggers:
|
Triggers:
|
||||||
|
|
||||||
- Manual Workflow Dispatch Trigger
|
- Manual Workflow Dispatch Trigger
|
||||||
|
|
||||||
This job is responsible for delivering the latest version of budibase to those that are self-hosting.
|
This job is responsible for delivering the latest version of budibase to those that are self-hosting.
|
||||||
|
|
||||||
This job relies on the release job to have run first, so the latest image is pushed to dockerhub. This job then will pull the latest version from `lerna.json` and try to find an image in dockerhub corresponding to that version. For example, if the version in `lerna.json` is `1.0.0`:
|
This job relies on the release job to have run first, so the latest image is pushed to dockerhub. This job then will pull the latest version from `lerna.json` and try to find an image in dockerhub corresponding to that version. For example, if the version in `lerna.json` is `1.0.0`:
|
||||||
|
|
||||||
- Pull the images for all budibase services tagged `v1.0.0` from dockerhub
|
- Pull the images for all budibase services tagged `v1.0.0` from dockerhub
|
||||||
- Tag these images as `latest`
|
- Tag these images as `latest`
|
||||||
- Push them back to dockerhub. This now means anyone who pulls `latest` (self hosters using docker-compose) will get the latest version.
|
- Push them back to dockerhub. This now means anyone who pulls `latest` (self hosters using docker-compose) will get the latest version.
|
||||||
|
@ -58,53 +70,61 @@ This job relies on the release job to have run first, so the latest image is pus
|
||||||
- Perform a github release with the latest version. You can see previous releases here (https://github.com/Budibase/budibase/releases)
|
- Perform a github release with the latest version. You can see previous releases here (https://github.com/Budibase/budibase/releases)
|
||||||
|
|
||||||
### Deploy Release (deploy-release.yml)
|
### Deploy Release (deploy-release.yml)
|
||||||
|
|
||||||
Triggers:
|
Triggers:
|
||||||
|
|
||||||
- Manual Workflow Dispatch Trigger
|
- Manual Workflow Dispatch Trigger
|
||||||
|
|
||||||
This job is responsible for deploying to our release, cloud kubernetes environment. You must run the release job first, to ensure that the latest images have been built and pushed to docker hub. After kicking off this job, the following will occur:
|
This job is responsible for deploying to our release, cloud kubernetes environment. You must run the release job first, to ensure that the latest images have been built and pushed to docker hub. After kicking off this job, the following will occur:
|
||||||
|
|
||||||
- Checks out the release branch
|
- Checks out the release branch
|
||||||
- Pulls the latest `values.yaml` from budibase infra, a private repo containing budibases infrastructure configuration
|
- Pulls the latest `values.yaml` from budibase infra, a private repo containing budibases infrastructure configuration
|
||||||
- Gets the latest budibase version from `lerna.json`, if it hasn't been specified in the workflow when you kicked it off
|
- Gets the latest budibase version from `lerna.json`, if it hasn't been specified in the workflow when you kicked it off
|
||||||
- Configures AWS Credentials
|
- Configures AWS Credentials
|
||||||
- Deploys the helm chart in the budibase repo to our preproduction EKS cluster, injecting the `values.yaml` we pulled from budibase-infra
|
- Deploys the helm chart in the budibase repo to our preproduction EKS cluster, injecting the `values.yaml` we pulled from budibase-infra
|
||||||
- Fires off a discord webhook in the #infra channel to show that the deployment completely successfully.
|
- Fires off a discord webhook in the #infra channel to show that the deployment completely successfully.
|
||||||
|
|
||||||
### Deploy Preprod (deploy-preprod.yml)
|
### Deploy Preprod (deploy-preprod.yml)
|
||||||
|
|
||||||
Triggers:
|
Triggers:
|
||||||
|
|
||||||
- Manual Workflow Dispatch Trigger
|
- Manual Workflow Dispatch Trigger
|
||||||
|
|
||||||
This job is responsible for deploying to our preprod, cloud kubernetes environment. You must run the release job first, to ensure that the latest images have been built and pushed to docker hub. After kicking off this job, the following will occur:
|
This job is responsible for deploying to our preprod, cloud kubernetes environment. You must run the release job first, to ensure that the latest images have been built and pushed to docker hub. After kicking off this job, the following will occur:
|
||||||
|
|
||||||
- Checks out the master branch
|
- Checks out the master branch
|
||||||
- Pulls the latest `values.yaml` from budibase infra, a private repo containing budibases infrastructure configuration
|
- Pulls the latest `values.yaml` from budibase infra, a private repo containing budibases infrastructure configuration
|
||||||
- Gets the latest budibase version from `lerna.json`, if it hasn't been specified in the workflow when you kicked it off
|
- Gets the latest budibase version from `lerna.json`, if it hasn't been specified in the workflow when you kicked it off
|
||||||
- Configures AWS Credentials
|
- Configures AWS Credentials
|
||||||
- Deploys the helm chart in the budibase repo to our preprod EKS cluster, injecting the `values.yaml` we pulled from budibase-infra
|
- Deploys the helm chart in the budibase repo to our preprod EKS cluster, injecting the `values.yaml` we pulled from budibase-infra
|
||||||
- Fires off a discord webhook in the #infra channel to show that the deployment completely successfully.
|
- Fires off a discord webhook in the #infra channel to show that the deployment completely successfully.
|
||||||
|
|
||||||
### Deploy Production (deploy-cloud.yml)
|
### Deploy Production (deploy-cloud.yml)
|
||||||
|
|
||||||
Triggers:
|
Triggers:
|
||||||
|
|
||||||
- Manual Workflow Dispatch Trigger
|
- Manual Workflow Dispatch Trigger
|
||||||
|
|
||||||
This job is responsible for deploying to our production, cloud kubernetes environment. You must run the release job first, to ensure that the latest images have been built and pushed to docker hub. You can also manually enter a version number for this job, so you can perform rollbacks or upgrade to a specific version. After kicking off this job, the following will occur:
|
This job is responsible for deploying to our production, cloud kubernetes environment. You must run the release job first, to ensure that the latest images have been built and pushed to docker hub. You can also manually enter a version number for this job, so you can perform rollbacks or upgrade to a specific version. After kicking off this job, the following will occur:
|
||||||
|
|
||||||
- Checks out the master branch
|
- Checks out the master branch
|
||||||
- Pulls the latest `values.yaml` from budibase infra, a private repo containing budibases infrastructure configuration
|
- Pulls the latest `values.yaml` from budibase infra, a private repo containing budibases infrastructure configuration
|
||||||
- Gets the latest budibase version from `lerna.json`, if it hasn't been specified in the workflow when you kicked it off
|
- Gets the latest budibase version from `lerna.json`, if it hasn't been specified in the workflow when you kicked it off
|
||||||
- Configures AWS Credentials
|
- Configures AWS Credentials
|
||||||
- Deploys the helm chart in the budibase repo to our production EKS cluster, injecting the `values.yaml` we pulled from budibase-infra
|
- Deploys the helm chart in the budibase repo to our production EKS cluster, injecting the `values.yaml` we pulled from budibase-infra
|
||||||
- Fires off a discord webhook in the #infra channel to show that the deployment completely successfully.
|
- Fires off a discord webhook in the #infra channel to show that the deployment completely successfully.
|
||||||
|
|
||||||
## Common Workflows
|
## Common Workflows
|
||||||
|
|
||||||
### Deploy Changes to Production (Release)
|
### Deploy Changes to Production (Release)
|
||||||
|
|
||||||
- Merge `develop` into `master`
|
- Merge `develop` into `master`
|
||||||
- Wait for budibase CI job and release job to run
|
- Wait for budibase CI job and release job to run
|
||||||
- Run cloud deploy job
|
- Run cloud deploy job
|
||||||
- Run release selfhost job
|
- Run release selfhost job
|
||||||
|
|
||||||
### Deploy Changes to Production (Hotfix)
|
### Deploy Changes to Production (Hotfix)
|
||||||
|
|
||||||
- Branch off `master`
|
- Branch off `master`
|
||||||
- Perform your hotfix
|
- Perform your hotfix
|
||||||
- Merge back into `master`
|
- Merge back into `master`
|
||||||
|
@ -113,79 +133,7 @@ This job is responsible for deploying to our production, cloud kubernetes enviro
|
||||||
- Run release selfhost job
|
- Run release selfhost job
|
||||||
|
|
||||||
### Rollback A Bad Cloud Deployment
|
### Rollback A Bad Cloud Deployment
|
||||||
|
|
||||||
- Kick off cloud deploy job
|
- Kick off cloud deploy job
|
||||||
- Ensure you are running off master
|
- Ensure you are running off master
|
||||||
- Enter the version number of the last known good version of budibase. For example `1.0.0`
|
- Enter the version number of the last known good version of budibase. For example `1.0.0`
|
||||||
|
|
||||||
## Pro
|
|
||||||
|
|
||||||
| **NOTE**: When developing for both pro / budibase repositories, your branch names need to match, or else the correct pro doesn't get run within your CI job.
|
|
||||||
|
|
||||||
### Installing Pro
|
|
||||||
|
|
||||||
The pro package is always installed from source in our CI jobs.
|
|
||||||
|
|
||||||
This is done to prevent pro needing to be published prior to CI runs in budiabse. This is required for two reasons:
|
|
||||||
- To reduce developer need to manually bump versions, i.e:
|
|
||||||
- release pro, bump pro dep in budibase, now ci can run successfully
|
|
||||||
- The cyclic dependency on backend-core, i.e:
|
|
||||||
- pro depends on backend-core
|
|
||||||
- server depends on pro
|
|
||||||
- backend-core lives in the monorepo, so it can't be released independently to be used in pro
|
|
||||||
- therefore the only option is to pull pro from source and release it as a part of the monorepo release, as if it were a mono package
|
|
||||||
|
|
||||||
The install is performed using the same steps as local development, via the `yarn bootstrap` command, see the [Contributing Guide#Pro](../../docs/CONTRIBUTING.md#pro)
|
|
||||||
|
|
||||||
The branch to install pro from can vary depending on ref of the commit that triggered the budibase CI job. This is done to enable branches which have changes in both the monorepo and the pro repo to have their CI pass successfully.
|
|
||||||
|
|
||||||
This is done using the [pro/install.sh](../../scripts/pro/install.sh) script. The script will:
|
|
||||||
- Clone pro to it's default branch (`develop`)
|
|
||||||
- Check if the clone worked, on forked versions of budibase this will fail due to no access
|
|
||||||
- This is fine as the `yarn` command will install the version from NPM
|
|
||||||
- Community PRs should never touch pro so this will always work
|
|
||||||
- Checkout the `BRANCH` argument, if this fails fallback to `BASE_BRANCH`
|
|
||||||
- This enables the more complex case of a feature branch being merged to another feature branch, e.g.
|
|
||||||
- I am working on a branch `epic/stonks` which exists on budibase and pro.
|
|
||||||
- I want to merge a change to this branch in budibase from `feature/stonks-ui`, which only exists in budibase
|
|
||||||
- The base branch ensures that `epic/stonks` in pro will still be checked out for the CI run, rather than falling back to `develop`
|
|
||||||
- Run `yarn setup` to build and install dependencies
|
|
||||||
- `yarn`
|
|
||||||
- `yarn bootstrap`
|
|
||||||
- `yarn build`
|
|
||||||
- The will build .ts files, and also update the `main` and `types` of `package.json` to point to `dist` rather than src
|
|
||||||
- The build command will only ever work in CI, it is prevented in local dev
|
|
||||||
|
|
||||||
#### `BRANCH` and `BASE_BRANCH` arguments
|
|
||||||
These arguments are supplied by the various budibase build and release pipelines
|
|
||||||
- `budibase_ci`
|
|
||||||
- `BRANCH: ${{ github.event.pull_request.head.ref }}` -> The branch being merged
|
|
||||||
- `BASE_BRANCH: ${{ github.event.pull_request.base.ref}}` -> The base branch
|
|
||||||
- `release-develop`
|
|
||||||
- `BRANCH: develop` -> always use the `develop` branch in pro
|
|
||||||
- `release`
|
|
||||||
- `BRANCH: master` -> always use the `master` branch in pro
|
|
||||||
|
|
||||||
|
|
||||||
### Releasing Pro
|
|
||||||
After budibase dependencies have been released we will release the new version of pro to match the release version of budibase dependencies. This is to ensure that we are always keeping the version of `backend-core` in sync in the pro package and in budibase packages. Without this we could run into scenarios where different versions are being used when installed via `yarn` inside the docker images, creating very difficult to debug cases.
|
|
||||||
|
|
||||||
Pro is released using the [pro/release.sh](../../scripts/pro/release.sh) script. The script will:
|
|
||||||
- Inspect the `VERSION` from the `lerna.json` file in budibase
|
|
||||||
- Determine whether to use the `latest` or `develop` tag based on the command argument
|
|
||||||
- Go to pro directory
|
|
||||||
- install npm creds
|
|
||||||
- update the version of `backend-core` to be `VERSION`, the version just released by lerna
|
|
||||||
- publish to npm. Uses a `lerna publish` command, pro itself is a mono repo.
|
|
||||||
- force the version to be the same as `VERSION` to keep pro and budibase in sync
|
|
||||||
- reverts the changes to `main` and `types` in `package.json` that were made by the build step, to point back to source
|
|
||||||
- commit & push: `Prep next development iteration`
|
|
||||||
- Go to budibase
|
|
||||||
- Update to the new version of pro in `server` and `worker` so the latest pro version is used in the docker builds
|
|
||||||
- commit & push: `Update pro version to $VERSION`
|
|
||||||
|
|
||||||
|
|
||||||
#### `COMMAND` argument
|
|
||||||
This argument is supplied by the existing `release` and `release:develop` budibase commands, which invoke the pro release
|
|
||||||
- `release` will supply no command and default to use `latest`
|
|
||||||
- `release:develop` will supply `develop`
|
|
||||||
|
|
||||||
|
|
|
@ -214,6 +214,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Check pro commit
|
- name: Check pro commit
|
||||||
id: get_pro_commits
|
id: get_pro_commits
|
||||||
|
@ -251,4 +252,4 @@ jobs:
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
} else {
|
} else {
|
||||||
console.log('All good, the submodule had been merged and setup correctly!')
|
console.log('All good, the submodule had been merged and setup correctly!')
|
||||||
}
|
}
|
|
@ -36,7 +36,7 @@ jobs:
|
||||||
|
|
||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: 14.x
|
node-version: 18.x
|
||||||
|
|
||||||
- run: yarn install --frozen-lockfile
|
- run: yarn install --frozen-lockfile
|
||||||
- name: Update versions
|
- name: Update versions
|
||||||
|
|
|
@ -28,10 +28,10 @@ jobs:
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Use Node.js 14.x
|
- name: Use Node.js 18.x
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: 14.x
|
node-version: 18.x
|
||||||
|
|
||||||
- name: Get the latest budibase release version
|
- name: Get the latest budibase release version
|
||||||
id: version
|
id: version
|
||||||
|
@ -67,7 +67,6 @@ jobs:
|
||||||
- name: Bootstrap and build (CLI)
|
- name: Bootstrap and build (CLI)
|
||||||
run: |
|
run: |
|
||||||
yarn
|
yarn
|
||||||
yarn bootstrap
|
|
||||||
yarn build
|
yarn build
|
||||||
|
|
||||||
- name: Build OpenAPI spec
|
- name: Build OpenAPI spec
|
||||||
|
|
|
@ -13,7 +13,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [14.x]
|
node-version: [18.x]
|
||||||
steps:
|
steps:
|
||||||
- name: Maximize build space
|
- name: Maximize build space
|
||||||
uses: easimon/maximize-build-space@master
|
uses: easimon/maximize-build-space@master
|
||||||
|
|
|
@ -97,8 +97,6 @@ typings/
|
||||||
|
|
||||||
bin/
|
bin/
|
||||||
hosting/.generated*
|
hosting/.generated*
|
||||||
packages/builder/cypress.env.json
|
|
||||||
packages/builder/cypress/reports
|
|
||||||
stats.html
|
stats.html
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,4 @@ packages/backend-core/coverage
|
||||||
packages/server/client
|
packages/server/client
|
||||||
packages/server/src/definitions/openapi.ts
|
packages/server/src/definitions/openapi.ts
|
||||||
packages/builder/.routify
|
packages/builder/.routify
|
||||||
packages/builder/cypress/support/queryLevelTransformerFunction.js
|
|
||||||
packages/builder/cypress/support/queryLevelTransformerFunctionWithData.js
|
|
||||||
packages/sdk/sdk
|
packages/sdk/sdk
|
|
@ -1,4 +1,5 @@
|
||||||
{{- if .Values.globals.createSecrets -}}
|
{{- $existingSecret := lookup "v1" "Secret" .Release.Namespace (include "budibase.fullname" .) }}
|
||||||
|
{{- if .Values.globals.createSecrets }}
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
|
@ -10,8 +11,15 @@ metadata:
|
||||||
heritage: "{{ .Release.Service }}"
|
heritage: "{{ .Release.Service }}"
|
||||||
type: Opaque
|
type: Opaque
|
||||||
data:
|
data:
|
||||||
|
{{- if $existingSecret }}
|
||||||
|
internalApiKey: {{ index $existingSecret.data "internalApiKey" }}
|
||||||
|
jwtSecret: {{ index $existingSecret.data "jwtSecret" }}
|
||||||
|
objectStoreAccess: {{ index $existingSecret.data "objectStoreAccess" }}
|
||||||
|
objectStoreSecret: {{ index $existingSecret.data "objectStoreSecret" }}
|
||||||
|
{{- else }}
|
||||||
internalApiKey: {{ template "budibase.defaultsecret" .Values.globals.internalApiKey }}
|
internalApiKey: {{ template "budibase.defaultsecret" .Values.globals.internalApiKey }}
|
||||||
jwtSecret: {{ template "budibase.defaultsecret" .Values.globals.jwtSecret }}
|
jwtSecret: {{ template "budibase.defaultsecret" .Values.globals.jwtSecret }}
|
||||||
objectStoreAccess: {{ template "budibase.defaultsecret" .Values.services.objectStore.accessKey }}
|
objectStoreAccess: {{ template "budibase.defaultsecret" .Values.services.objectStore.accessKey }}
|
||||||
objectStoreSecret: {{ template "budibase.defaultsecret" .Values.services.objectStore.secretKey }}
|
objectStoreSecret: {{ template "budibase.defaultsecret" .Values.services.objectStore.secretKey }}
|
||||||
{{- end -}}
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
|
@ -264,16 +264,14 @@ Sometimes, things go wrong. This can be due to incompatible updates on the budib
|
||||||
|
|
||||||
### Running tests
|
### Running tests
|
||||||
|
|
||||||
#### End-to-end Tests
|
#### Unit Tests
|
||||||
|
|
||||||
Budibase uses Cypress to run a number of E2E tests. To run the tests execute the following command in the root folder:
|
Budibase uses Jest to run a number of tests. To run the tests execute the following command in the root folder:
|
||||||
|
|
||||||
```
|
```
|
||||||
yarn test:e2e
|
yarn test
|
||||||
```
|
```
|
||||||
|
|
||||||
Or if you are in the builder you can run `yarn cy:test`.
|
|
||||||
|
|
||||||
### Other Useful Information
|
### Other Useful Information
|
||||||
|
|
||||||
- The contributors are listed in [AUTHORS.md](https://github.com/Budibase/budibase/blob/master/.github/AUTHORS.md) (add yourself).
|
- The contributors are listed in [AUTHORS.md](https://github.com/Budibase/budibase/blob/master/.github/AUTHORS.md) (add yourself).
|
||||||
|
|
|
@ -55,7 +55,7 @@ yarn setup
|
||||||
The yarn setup command runs several build steps i.e.
|
The yarn setup command runs several build steps i.e.
|
||||||
|
|
||||||
```
|
```
|
||||||
node ./hosting/scripts/setup.js && yarn && yarn bootstrap && yarn build && yarn dev
|
node ./hosting/scripts/setup.js && yarn && yarn build && yarn dev
|
||||||
```
|
```
|
||||||
|
|
||||||
So this command will actually run the application in dev mode. It creates .env files under `./packages/server` and `./packages/worker` and runs docker containers for each service via docker-compose.
|
So this command will actually run the application in dev mode. It creates .env files under `./packages/server` and `./packages/worker` and runs docker containers for each service via docker-compose.
|
||||||
|
|
|
@ -55,7 +55,7 @@ yarn setup
|
||||||
The yarn setup command runs several build steps i.e.
|
The yarn setup command runs several build steps i.e.
|
||||||
|
|
||||||
```
|
```
|
||||||
node ./hosting/scripts/setup.js && yarn && yarn bootstrap && yarn build && yarn dev
|
node ./hosting/scripts/setup.js && yarn && yarn build && yarn dev
|
||||||
```
|
```
|
||||||
|
|
||||||
So this command will actually run the application in dev mode. It creates .env files under `./packages/server` and `./packages/worker` and runs docker containers for each service via docker-compose.
|
So this command will actually run the application in dev mode. It creates .env files under `./packages/server` and `./packages/worker` and runs docker containers for each service via docker-compose.
|
||||||
|
|
|
@ -74,7 +74,7 @@ yarn setup
|
||||||
The yarn setup command runs several build steps i.e.
|
The yarn setup command runs several build steps i.e.
|
||||||
|
|
||||||
```
|
```
|
||||||
node ./hosting/scripts/setup.js && yarn && yarn bootstrap && yarn build && yarn dev
|
node ./hosting/scripts/setup.js && yarn && yarn build && yarn dev
|
||||||
```
|
```
|
||||||
|
|
||||||
So this command will actually run the application in dev mode. It creates .env files under `./packages/server` and `./packages/worker` and runs docker containers for each service via docker-compose.
|
So this command will actually run the application in dev mode. It creates .env files under `./packages/server` and `./packages/worker` and runs docker containers for each service via docker-compose.
|
||||||
|
|
|
@ -58,7 +58,6 @@ Node setup:
|
||||||
```
|
```
|
||||||
node ./hosting/scripts/setup.js
|
node ./hosting/scripts/setup.js
|
||||||
yarn
|
yarn
|
||||||
yarn bootstrap
|
|
||||||
yarn build
|
yarn build
|
||||||
```
|
```
|
||||||
#### Build Image
|
#### Build Image
|
||||||
|
|
|
@ -47,7 +47,6 @@ Node setup:
|
||||||
```
|
```
|
||||||
node ./hosting/scripts/setup.js
|
node ./hosting/scripts/setup.js
|
||||||
yarn
|
yarn
|
||||||
yarn bootstrap
|
|
||||||
yarn build
|
yarn build
|
||||||
```
|
```
|
||||||
#### Build Image
|
#### Build Image
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "2.9.33-alpha.13",
|
"version": "2.9.40-alpha.7",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
|
|
15
package.json
15
package.json
|
@ -9,7 +9,6 @@
|
||||||
"esbuild": "^0.18.17",
|
"esbuild": "^0.18.17",
|
||||||
"esbuild-node-externals": "^1.8.0",
|
"esbuild-node-externals": "^1.8.0",
|
||||||
"eslint": "^8.44.0",
|
"eslint": "^8.44.0",
|
||||||
"eslint-plugin-cypress": "^2.11.3",
|
|
||||||
"husky": "^8.0.3",
|
"husky": "^8.0.3",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"kill-port": "^1.6.1",
|
"kill-port": "^1.6.1",
|
||||||
|
@ -33,25 +32,22 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"preinstall": "node scripts/syncProPackage.js",
|
"preinstall": "node scripts/syncProPackage.js",
|
||||||
"setup": "git config submodule.recurse true && git submodule update && node ./hosting/scripts/setup.js && yarn && yarn build && yarn dev",
|
"setup": "git config submodule.recurse true && git submodule update && node ./hosting/scripts/setup.js && yarn && yarn build && yarn dev",
|
||||||
"bootstrap": "./scripts/link-dependencies.sh && echo '***BOOTSTRAP ONLY REQUIRED FOR USE WITH ACCOUNT PORTAL***'",
|
|
||||||
"build": "lerna run build --stream",
|
"build": "lerna run build --stream",
|
||||||
"build:dev": "lerna run --stream prebuild && yarn nx run-many --target=build --output-style=dynamic --watch --preserveWatchOutput",
|
"build:dev": "lerna run --stream prebuild && yarn nx run-many --target=build --output-style=dynamic --watch --preserveWatchOutput",
|
||||||
"check:types": "lerna run check:types",
|
"check:types": "lerna run check:types",
|
||||||
"backend:bootstrap": "./scripts/scopeBackend.sh && yarn run bootstrap",
|
|
||||||
"backend:build": "./scripts/scopeBackend.sh 'lerna run --stream build'",
|
|
||||||
"build:sdk": "lerna run --stream build:sdk",
|
"build:sdk": "lerna run --stream build:sdk",
|
||||||
"deps:circular": "madge packages/server/dist/index.js packages/worker/src/index.ts packages/backend-core/dist/src/index.js packages/cli/src/index.js --circular",
|
"deps:circular": "madge packages/server/dist/index.js packages/worker/src/index.ts packages/backend-core/dist/src/index.js packages/cli/src/index.js --circular",
|
||||||
"release": "lerna publish from-package --yes --force-publish --no-git-tag-version --no-push --no-git-reset",
|
"release": "lerna publish from-package --yes --force-publish --no-git-tag-version --no-push --no-git-reset",
|
||||||
"release:develop": "yarn release --dist-tag develop",
|
"release:develop": "yarn release --dist-tag develop",
|
||||||
"restore": "yarn run clean && yarn run bootstrap && yarn run build",
|
"restore": "yarn run clean && yarn && yarn run build",
|
||||||
"nuke": "yarn run nuke:packages && yarn run nuke:docker",
|
"nuke": "yarn run nuke:packages && yarn run nuke:docker",
|
||||||
"nuke:packages": "yarn run restore",
|
"nuke:packages": "yarn run restore",
|
||||||
"nuke:docker": "lerna run --stream dev:stack:nuke",
|
"nuke:docker": "lerna run --stream dev:stack:nuke",
|
||||||
"clean": "lerna clean",
|
"clean": "lerna clean -y",
|
||||||
"kill-builder": "kill-port 3000",
|
"kill-builder": "kill-port 3000",
|
||||||
"kill-server": "kill-port 4001 4002",
|
"kill-server": "kill-port 4001 4002",
|
||||||
"kill-all": "yarn run kill-builder && yarn run kill-server",
|
"kill-all": "yarn run kill-builder && yarn run kill-server",
|
||||||
"dev": "yarn run kill-all && lerna run --stream dev:builder",
|
"dev": "yarn run kill-all && lerna run --parallel prebuild && lerna run --stream dev:builder",
|
||||||
"dev:noserver": "yarn run kill-builder && lerna run --stream dev:stack:up && lerna run --stream dev:builder --ignore @budibase/backend-core --ignore @budibase/server --ignore @budibase/worker",
|
"dev:noserver": "yarn run kill-builder && lerna run --stream dev:stack:up && lerna run --stream dev:builder --ignore @budibase/backend-core --ignore @budibase/server --ignore @budibase/worker",
|
||||||
"dev:server": "yarn run kill-server && lerna run --stream dev:builder --scope @budibase/worker --scope @budibase/server",
|
"dev:server": "yarn run kill-server && lerna run --stream dev:builder --scope @budibase/worker --scope @budibase/server",
|
||||||
"dev:built": "yarn run kill-all && cd packages/server && yarn dev:stack:up && cd ../../ && lerna run --stream dev:built",
|
"dev:built": "yarn run kill-all && cd packages/server && yarn dev:stack:up && cd ../../ && lerna run --stream dev:built",
|
||||||
|
@ -93,9 +89,8 @@
|
||||||
"mode:account": "yarn mode:cloud && yarn env:account:enable",
|
"mode:account": "yarn mode:cloud && yarn env:account:enable",
|
||||||
"security:audit": "node scripts/audit.js",
|
"security:audit": "node scripts/audit.js",
|
||||||
"postinstall": "husky install",
|
"postinstall": "husky install",
|
||||||
"dep:clean": "yarn clean -y && yarn bootstrap",
|
"submodules:load": "git submodule init && git submodule update && yarn",
|
||||||
"submodules:load": "git submodule init && git submodule update && yarn && yarn bootstrap",
|
"submodules:unload": "git submodule deinit --all && yarn"
|
||||||
"submodules:unload": "git submodule deinit --all && yarn && yarn bootstrap"
|
|
||||||
},
|
},
|
||||||
"workspaces": {
|
"workspaces": {
|
||||||
"packages": [
|
"packages": [
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
*
|
*
|
||||||
!dist/**/*
|
!dist/**/*
|
||||||
dist/tsconfig.build.tsbuildinfo
|
dist/tsconfig.build.tsbuildinfo
|
||||||
!package.json
|
!package.json
|
||||||
|
!src/**
|
||||||
|
!tests/**
|
|
@ -6,7 +6,7 @@
|
||||||
"types": "dist/src/index.d.ts",
|
"types": "dist/src/index.d.ts",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./dist/index.js",
|
".": "./dist/index.js",
|
||||||
"./tests": "./dist/tests.js",
|
"./tests": "./dist/tests/index.js",
|
||||||
"./*": "./dist/*.js"
|
"./*": "./dist/*.js"
|
||||||
},
|
},
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prebuild": "rimraf dist/",
|
"prebuild": "rimraf dist/",
|
||||||
"prepack": "cp package.json dist",
|
"prepack": "cp package.json dist",
|
||||||
"build": "node ./scripts/build.js && tsc -p tsconfig.build.json --emitDeclarationOnly --paths null",
|
"build": "tsc -p tsconfig.build.json --paths null && node ./scripts/build.js",
|
||||||
"build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput",
|
"build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput",
|
||||||
"check:types": "tsc -p tsconfig.json --noEmit --paths null",
|
"check:types": "tsc -p tsconfig.json --noEmit --paths null",
|
||||||
"test": "bash scripts/test.sh",
|
"test": "bash scripts/test.sh",
|
||||||
|
@ -68,8 +68,8 @@
|
||||||
"@types/jest": "29.5.3",
|
"@types/jest": "29.5.3",
|
||||||
"@types/koa": "2.13.4",
|
"@types/koa": "2.13.4",
|
||||||
"@types/lodash": "4.14.180",
|
"@types/lodash": "4.14.180",
|
||||||
"@types/node": "14.18.20",
|
"@types/node": "18.17.0",
|
||||||
"@types/node-fetch": "2.6.1",
|
"@types/node-fetch": "2.6.4",
|
||||||
"@types/pouchdb": "6.4.0",
|
"@types/pouchdb": "6.4.0",
|
||||||
"@types/redlock": "4.0.3",
|
"@types/redlock": "4.0.3",
|
||||||
"@types/semver": "7.3.7",
|
"@types/semver": "7.3.7",
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
#!/usr/bin/node
|
#!/usr/bin/node
|
||||||
const coreBuild = require("../../../scripts/build")
|
const coreBuild = require("../../../scripts/build")
|
||||||
|
|
||||||
coreBuild("./src/plugin/index.ts", "./dist/plugins.js")
|
|
||||||
coreBuild("./src/index.ts", "./dist/index.js")
|
coreBuild("./src/index.ts", "./dist/index.js")
|
||||||
coreBuild("./tests/index.ts", "./dist/tests.js")
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ export async function getAppMetadata(appId: string): Promise<App | DeletedApp> {
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// needed for cypress/some scenarios where the caching happens
|
// needed for some scenarios where the caching happens
|
||||||
// so quickly the requests can get slightly out of sync
|
// so quickly the requests can get slightly out of sync
|
||||||
// might store its invalid just before it stores its valid
|
// might store its invalid just before it stores its valid
|
||||||
if (isInvalid(metadata)) {
|
if (isInvalid(metadata)) {
|
||||||
|
|
|
@ -22,6 +22,8 @@ export enum Header {
|
||||||
TENANT_ID = "x-budibase-tenant-id",
|
TENANT_ID = "x-budibase-tenant-id",
|
||||||
VERIFICATION_CODE = "x-budibase-verification-code",
|
VERIFICATION_CODE = "x-budibase-verification-code",
|
||||||
RETURN_VERIFICATION_CODE = "x-budibase-return-verification-code",
|
RETURN_VERIFICATION_CODE = "x-budibase-return-verification-code",
|
||||||
|
RESET_PASSWORD_CODE = "x-budibase-reset-password-code",
|
||||||
|
RETURN_RESET_PASSWORD_CODE = "x-budibase-return-reset-password-code",
|
||||||
TOKEN = "x-budibase-token",
|
TOKEN = "x-budibase-token",
|
||||||
CSRF_TOKEN = "x-csrf-token",
|
CSRF_TOKEN = "x-csrf-token",
|
||||||
CORRELATION_ID = "x-budibase-correlation-id",
|
CORRELATION_ID = "x-budibase-correlation-id",
|
||||||
|
|
|
@ -8,7 +8,6 @@ import {
|
||||||
DatabasePutOpts,
|
DatabasePutOpts,
|
||||||
DatabaseCreateIndexOpts,
|
DatabaseCreateIndexOpts,
|
||||||
DatabaseDeleteIndexOpts,
|
DatabaseDeleteIndexOpts,
|
||||||
DocExistsResponse,
|
|
||||||
Document,
|
Document,
|
||||||
isDocument,
|
isDocument,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
@ -121,19 +120,6 @@ export class DatabaseImpl implements Database {
|
||||||
return this.updateOutput(() => db.get(id))
|
return this.updateOutput(() => db.get(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
async docExists(docId: string): Promise<DocExistsResponse> {
|
|
||||||
const db = await this.checkSetup()
|
|
||||||
let _rev, exists
|
|
||||||
try {
|
|
||||||
const { etag } = await db.head(docId)
|
|
||||||
_rev = etag
|
|
||||||
exists = true
|
|
||||||
} catch (err) {
|
|
||||||
exists = false
|
|
||||||
}
|
|
||||||
return { _rev, exists }
|
|
||||||
}
|
|
||||||
|
|
||||||
async remove(idOrDoc: string | Document, rev?: string) {
|
async remove(idOrDoc: string | Document, rev?: string) {
|
||||||
const db = await this.checkSetup()
|
const db = await this.checkSetup()
|
||||||
let _id: string
|
let _id: string
|
||||||
|
|
|
@ -11,7 +11,11 @@ export function getDB(dbName?: string, opts?: any): Database {
|
||||||
// we have to use a callback for this so that we can close
|
// we have to use a callback for this so that we can close
|
||||||
// the DB when we're done, without this manual requests would
|
// the DB when we're done, without this manual requests would
|
||||||
// need to close the database when done with it to avoid memory leaks
|
// need to close the database when done with it to avoid memory leaks
|
||||||
export async function doWithDB(dbName: string, cb: any, opts = {}) {
|
export async function doWithDB<T>(
|
||||||
|
dbName: string,
|
||||||
|
cb: (db: Database) => Promise<T>,
|
||||||
|
opts = {}
|
||||||
|
) {
|
||||||
const db = getDB(dbName, opts)
|
const db = getDB(dbName, opts)
|
||||||
// need this to be async so that we can correctly close DB after all
|
// need this to be async so that we can correctly close DB after all
|
||||||
// async operations have been completed
|
// async operations have been completed
|
||||||
|
|
|
@ -2,15 +2,15 @@ import { existsSync, readFileSync } from "fs"
|
||||||
import { ServiceType } from "@budibase/types"
|
import { ServiceType } from "@budibase/types"
|
||||||
|
|
||||||
function isTest() {
|
function isTest() {
|
||||||
return isCypress() || isJest()
|
return isJest()
|
||||||
}
|
}
|
||||||
|
|
||||||
function isJest() {
|
function isJest() {
|
||||||
return !!(process.env.NODE_ENV === "jest" || process.env.JEST_WORKER_ID)
|
return (
|
||||||
}
|
process.env.NODE_ENV === "jest" ||
|
||||||
|
(process.env.JEST_WORKER_ID != null &&
|
||||||
function isCypress() {
|
process.env.JEST_WORKER_ID !== "null")
|
||||||
return process.env.NODE_ENV === "cypress"
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDev() {
|
function isDev() {
|
||||||
|
|
|
@ -253,7 +253,7 @@ export function checkForRoleResourceArray(
|
||||||
* Given an app ID this will retrieve all of the roles that are currently within that app.
|
* Given an app ID this will retrieve all of the roles that are currently within that app.
|
||||||
* @return {Promise<object[]>} An array of the role objects that were found.
|
* @return {Promise<object[]>} An array of the role objects that were found.
|
||||||
*/
|
*/
|
||||||
export async function getAllRoles(appId?: string) {
|
export async function getAllRoles(appId?: string): Promise<RoleDoc[]> {
|
||||||
if (appId) {
|
if (appId) {
|
||||||
return doWithDB(appId, internal)
|
return doWithDB(appId, internal)
|
||||||
} else {
|
} else {
|
||||||
|
@ -312,37 +312,6 @@ export async function getAllRoles(appId?: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This retrieves the required role for a resource
|
|
||||||
* @param permLevel The level of request
|
|
||||||
* @param resourceId The resource being requested
|
|
||||||
* @param subResourceId The sub resource being requested
|
|
||||||
* @return {Promise<{permissions}|Object>} returns the permissions required to access.
|
|
||||||
*/
|
|
||||||
export async function getRequiredResourceRole(
|
|
||||||
permLevel: string,
|
|
||||||
{ resourceId, subResourceId }: { resourceId?: string; subResourceId?: string }
|
|
||||||
) {
|
|
||||||
const roles = await getAllRoles()
|
|
||||||
let main = [],
|
|
||||||
sub = []
|
|
||||||
for (let role of roles) {
|
|
||||||
// no permissions, ignore it
|
|
||||||
if (!role.permissions) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
const mainRes = resourceId ? role.permissions[resourceId] : undefined
|
|
||||||
const subRes = subResourceId ? role.permissions[subResourceId] : undefined
|
|
||||||
if (mainRes && mainRes.indexOf(permLevel) !== -1) {
|
|
||||||
main.push(role._id)
|
|
||||||
} else if (subRes && subRes.indexOf(permLevel) !== -1) {
|
|
||||||
sub.push(role._id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// for now just return the IDs
|
|
||||||
return main.concat(sub)
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AccessController {
|
export class AccessController {
|
||||||
userHierarchies: { [key: string]: string[] }
|
userHierarchies: { [key: string]: string[] }
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -411,8 +380,8 @@ export function getDBRoleID(roleName: string) {
|
||||||
export function getExternalRoleID(roleId: string, version?: string) {
|
export function getExternalRoleID(roleId: string, version?: string) {
|
||||||
// for built-in roles we want to remove the DB role ID element (role_)
|
// for built-in roles we want to remove the DB role ID element (role_)
|
||||||
if (
|
if (
|
||||||
(roleId.startsWith(DocumentType.ROLE) && isBuiltin(roleId)) ||
|
roleId.startsWith(DocumentType.ROLE) &&
|
||||||
version === RoleIDVersion.NAME
|
(isBuiltin(roleId) || version === RoleIDVersion.NAME)
|
||||||
) {
|
) {
|
||||||
return roleId.split(`${DocumentType.ROLE}${SEPARATOR}`)[1]
|
return roleId.split(`${DocumentType.ROLE}${SEPARATOR}`)[1]
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ export default function positionDropdown(element, opts) {
|
||||||
useAnchorWidth,
|
useAnchorWidth,
|
||||||
offset = 5,
|
offset = 5,
|
||||||
customUpdate,
|
customUpdate,
|
||||||
|
offsetBelow,
|
||||||
} = opts
|
} = opts
|
||||||
if (!anchor) {
|
if (!anchor) {
|
||||||
return
|
return
|
||||||
|
@ -47,7 +48,7 @@ export default function positionDropdown(element, opts) {
|
||||||
styles.top = anchorBounds.top - elementBounds.height - offset
|
styles.top = anchorBounds.top - elementBounds.height - offset
|
||||||
styles.maxHeight = maxHeight || 240
|
styles.maxHeight = maxHeight || 240
|
||||||
} else {
|
} else {
|
||||||
styles.top = anchorBounds.bottom + offset
|
styles.top = anchorBounds.bottom + (offsetBelow || offset)
|
||||||
styles.maxHeight =
|
styles.maxHeight =
|
||||||
maxHeight || window.innerHeight - anchorBounds.bottom - 20
|
maxHeight || window.innerHeight - anchorBounds.bottom - 20
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
export let fetchTerm = null
|
export let fetchTerm = null
|
||||||
export let useFetch = false
|
export let useFetch = false
|
||||||
export let customPopoverHeight
|
export let customPopoverHeight
|
||||||
|
export let customPopoverOffsetBelow
|
||||||
|
export let customPopoverMaxHeight
|
||||||
|
export let open = false
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
@ -88,6 +91,7 @@
|
||||||
isPlaceholder={!arrayValue.length}
|
isPlaceholder={!arrayValue.length}
|
||||||
{autocomplete}
|
{autocomplete}
|
||||||
bind:fetchTerm
|
bind:fetchTerm
|
||||||
|
bind:open
|
||||||
{useFetch}
|
{useFetch}
|
||||||
{isOptionSelected}
|
{isOptionSelected}
|
||||||
{getOptionLabel}
|
{getOptionLabel}
|
||||||
|
@ -96,4 +100,6 @@
|
||||||
{sort}
|
{sort}
|
||||||
{autoWidth}
|
{autoWidth}
|
||||||
{customPopoverHeight}
|
{customPopoverHeight}
|
||||||
|
{customPopoverOffsetBelow}
|
||||||
|
{customPopoverMaxHeight}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -38,6 +38,8 @@
|
||||||
export let fetchTerm = null
|
export let fetchTerm = null
|
||||||
export let useFetch = false
|
export let useFetch = false
|
||||||
export let customPopoverHeight
|
export let customPopoverHeight
|
||||||
|
export let customPopoverOffsetBelow
|
||||||
|
export let customPopoverMaxHeight
|
||||||
export let align = "left"
|
export let align = "left"
|
||||||
export let footer = null
|
export let footer = null
|
||||||
export let customAnchor = null
|
export let customAnchor = null
|
||||||
|
@ -102,7 +104,7 @@
|
||||||
bind:this={button}
|
bind:this={button}
|
||||||
>
|
>
|
||||||
{#if fieldIcon}
|
{#if fieldIcon}
|
||||||
{#if !useOptionIconImage}x
|
{#if !useOptionIconImage}
|
||||||
<span class="option-extra icon">
|
<span class="option-extra icon">
|
||||||
<Icon size="S" name={fieldIcon} />
|
<Icon size="S" name={fieldIcon} />
|
||||||
</span>
|
</span>
|
||||||
|
@ -150,7 +152,9 @@
|
||||||
on:close={() => (open = false)}
|
on:close={() => (open = false)}
|
||||||
useAnchorWidth={!autoWidth}
|
useAnchorWidth={!autoWidth}
|
||||||
maxWidth={autoWidth ? 400 : null}
|
maxWidth={autoWidth ? 400 : null}
|
||||||
|
maxHeight={customPopoverMaxHeight}
|
||||||
customHeight={customPopoverHeight}
|
customHeight={customPopoverHeight}
|
||||||
|
offsetBelow={customPopoverOffsetBelow}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="popover-content"
|
class="popover-content"
|
||||||
|
|
|
@ -21,10 +21,12 @@
|
||||||
export let sort = false
|
export let sort = false
|
||||||
export let align
|
export let align
|
||||||
export let footer = null
|
export let footer = null
|
||||||
|
export let open = false
|
||||||
export let tag = null
|
export let tag = null
|
||||||
const dispatch = createEventDispatcher()
|
export let customPopoverOffsetBelow
|
||||||
|
export let customPopoverMaxHeight
|
||||||
|
|
||||||
let open = false
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
$: fieldText = getFieldText(value, options, placeholder)
|
$: fieldText = getFieldText(value, options, placeholder)
|
||||||
$: fieldIcon = getFieldAttribute(getOptionIcon, value, options)
|
$: fieldIcon = getFieldAttribute(getOptionIcon, value, options)
|
||||||
|
@ -84,6 +86,8 @@
|
||||||
{autocomplete}
|
{autocomplete}
|
||||||
{sort}
|
{sort}
|
||||||
{tag}
|
{tag}
|
||||||
|
{customPopoverOffsetBelow}
|
||||||
|
{customPopoverMaxHeight}
|
||||||
isPlaceholder={value == null || value === ""}
|
isPlaceholder={value == null || value === ""}
|
||||||
placeholderOption={placeholder === false ? null : placeholder}
|
placeholderOption={placeholder === false ? null : placeholder}
|
||||||
isOptionSelected={option => option === value}
|
isOptionSelected={option => option === value}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
export let useAnchorWidth = false
|
export let useAnchorWidth = false
|
||||||
export let dismissible = true
|
export let dismissible = true
|
||||||
export let offset = 5
|
export let offset = 5
|
||||||
|
export let offsetBelow
|
||||||
export let customHeight
|
export let customHeight
|
||||||
export let animate = true
|
export let animate = true
|
||||||
export let customZindex
|
export let customZindex
|
||||||
|
@ -89,6 +90,7 @@
|
||||||
maxWidth,
|
maxWidth,
|
||||||
useAnchorWidth,
|
useAnchorWidth,
|
||||||
offset,
|
offset,
|
||||||
|
offsetBelow,
|
||||||
customUpdate: handlePostionUpdate,
|
customUpdate: handlePostionUpdate,
|
||||||
}}
|
}}
|
||||||
use:clickOutside={{
|
use:clickOutside={{
|
||||||
|
|
|
@ -5,6 +5,4 @@ package-lock.json
|
||||||
release/
|
release/
|
||||||
dist/
|
dist/
|
||||||
routify
|
routify
|
||||||
cypress/videos
|
|
||||||
cypress/screenshots
|
|
||||||
.routify/
|
.routify/
|
|
@ -43,21 +43,10 @@
|
||||||
"/node_modules/(?!svelte).+\\.js$",
|
"/node_modules/(?!svelte).+\\.js$",
|
||||||
".*string-templates.*"
|
".*string-templates.*"
|
||||||
],
|
],
|
||||||
"modulePathIgnorePatterns": [
|
|
||||||
"<rootDir>/cypress/"
|
|
||||||
],
|
|
||||||
"setupFilesAfterEnv": [
|
"setupFilesAfterEnv": [
|
||||||
"@testing-library/jest-dom/extend-expect"
|
"@testing-library/jest-dom/extend-expect"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
|
||||||
"extends": [
|
|
||||||
"plugin:cypress/recommended"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"cypress/no-unnecessary-waiting": "off"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "0.0.0",
|
"@budibase/bbui": "0.0.0",
|
||||||
"@budibase/frontend-core": "0.0.0",
|
"@budibase/frontend-core": "0.0.0",
|
||||||
|
@ -104,9 +93,6 @@
|
||||||
"@testing-library/jest-dom": "5.17.0",
|
"@testing-library/jest-dom": "5.17.0",
|
||||||
"@testing-library/svelte": "^3.2.2",
|
"@testing-library/svelte": "^3.2.2",
|
||||||
"babel-jest": "29.6.2",
|
"babel-jest": "29.6.2",
|
||||||
"cypress": "^9.3.1",
|
|
||||||
"cypress-multi-reporters": "^1.6.0",
|
|
||||||
"cypress-terminal-report": "^1.4.1",
|
|
||||||
"identity-obj-proxy": "^3.0.0",
|
"identity-obj-proxy": "^3.0.0",
|
||||||
"jest": "29.6.2",
|
"jest": "29.6.2",
|
||||||
"jsdom": "^21.1.1",
|
"jsdom": "^21.1.1",
|
||||||
|
|
|
@ -955,7 +955,9 @@ export const buildFormSchema = (component, asset) => {
|
||||||
const patched = convertOldFieldFormat(component.fields || [])
|
const patched = convertOldFieldFormat(component.fields || [])
|
||||||
patched?.forEach(({ field, active }) => {
|
patched?.forEach(({ field, active }) => {
|
||||||
if (!active) return
|
if (!active) return
|
||||||
schema[field] = { type: info?.schema[field].type }
|
if (info?.schema[field]) {
|
||||||
|
schema[field] = { type: info?.schema[field].type }
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -627,6 +627,7 @@ export const getFrontendStore = () => {
|
||||||
component[setting.key] = {
|
component[setting.key] = {
|
||||||
label: defaultDS.name,
|
label: defaultDS.name,
|
||||||
tableId: defaultDS._id,
|
tableId: defaultDS._id,
|
||||||
|
resourceId: defaultDS._id,
|
||||||
type: "table",
|
type: "table",
|
||||||
}
|
}
|
||||||
} else if (setting.type === "dataProvider") {
|
} else if (setting.type === "dataProvider") {
|
||||||
|
@ -1245,6 +1246,13 @@ export const getFrontendStore = () => {
|
||||||
const settings = getComponentSettings(component._component)
|
const settings = getComponentSettings(component._component)
|
||||||
const updatedSetting = settings.find(setting => setting.key === name)
|
const updatedSetting = settings.find(setting => setting.key === name)
|
||||||
|
|
||||||
|
const resetFields = settings.filter(
|
||||||
|
setting => name === setting.resetOn
|
||||||
|
)
|
||||||
|
resetFields?.forEach(setting => {
|
||||||
|
component[setting.key] = null
|
||||||
|
})
|
||||||
|
|
||||||
if (
|
if (
|
||||||
updatedSetting?.type === "dataSource" ||
|
updatedSetting?.type === "dataSource" ||
|
||||||
updatedSetting?.type === "table"
|
updatedSetting?.type === "table"
|
||||||
|
|
|
@ -8,7 +8,7 @@ export default function (datasources) {
|
||||||
}
|
}
|
||||||
return datasources.map(datasource => {
|
return datasources.map(datasource => {
|
||||||
return {
|
return {
|
||||||
name: `${datasource.name} - List`,
|
name: `${datasource.label} - List`,
|
||||||
create: () => createScreen(datasource),
|
create: () => createScreen(datasource),
|
||||||
id: ROW_LIST_TEMPLATE,
|
id: ROW_LIST_TEMPLATE,
|
||||||
resourceId: datasource.resourceId,
|
resourceId: datasource.resourceId,
|
||||||
|
@ -17,13 +17,13 @@ export default function (datasources) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ROW_LIST_TEMPLATE = "ROW_LIST_TEMPLATE"
|
export const ROW_LIST_TEMPLATE = "ROW_LIST_TEMPLATE"
|
||||||
export const rowListUrl = datasource => sanitizeUrl(`/${datasource.name}`)
|
export const rowListUrl = datasource => sanitizeUrl(`/${datasource.label}`)
|
||||||
|
|
||||||
const generateTableBlock = datasource => {
|
const generateTableBlock = datasource => {
|
||||||
const tableBlock = new Component("@budibase/standard-components/tableblock")
|
const tableBlock = new Component("@budibase/standard-components/tableblock")
|
||||||
tableBlock
|
tableBlock
|
||||||
.customProps({
|
.customProps({
|
||||||
title: datasource.name,
|
title: datasource.label,
|
||||||
dataSource: datasource,
|
dataSource: datasource,
|
||||||
sortOrder: "Ascending",
|
sortOrder: "Ascending",
|
||||||
size: "spectrum--medium",
|
size: "spectrum--medium",
|
||||||
|
@ -34,14 +34,14 @@ const generateTableBlock = datasource => {
|
||||||
titleButtonText: "Create row",
|
titleButtonText: "Create row",
|
||||||
titleButtonClickBehaviour: "new",
|
titleButtonClickBehaviour: "new",
|
||||||
})
|
})
|
||||||
.instanceName(`${datasource.name} - Table block`)
|
.instanceName(`${datasource.label} - Table block`)
|
||||||
return tableBlock
|
return tableBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
const createScreen = datasource => {
|
const createScreen = datasource => {
|
||||||
return new Screen()
|
return new Screen()
|
||||||
.route(rowListUrl(datasource))
|
.route(rowListUrl(datasource))
|
||||||
.instanceName(`${datasource.name} - List`)
|
.instanceName(`${datasource.label} - List`)
|
||||||
.addChild(generateTableBlock(datasource))
|
.addChild(generateTableBlock(datasource))
|
||||||
.json()
|
.json()
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
import ManageAccessButton from "./buttons/ManageAccessButton.svelte"
|
import ManageAccessButton from "./buttons/ManageAccessButton.svelte"
|
||||||
import HideAutocolumnButton from "./buttons/HideAutocolumnButton.svelte"
|
import HideAutocolumnButton from "./buttons/HideAutocolumnButton.svelte"
|
||||||
import { notifications } from "@budibase/bbui"
|
import { notifications } from "@budibase/bbui"
|
||||||
|
import { ROW_EXPORT_FORMATS } from "constants/backend"
|
||||||
|
|
||||||
export let view = {}
|
export let view = {}
|
||||||
|
|
||||||
|
@ -19,6 +20,14 @@
|
||||||
let type = "internal"
|
let type = "internal"
|
||||||
|
|
||||||
$: name = view.name
|
$: name = view.name
|
||||||
|
$: calculation = view.calculation
|
||||||
|
|
||||||
|
$: supportedFormats = Object.values(ROW_EXPORT_FORMATS).filter(key => {
|
||||||
|
if (calculation && key === ROW_EXPORT_FORMATS.JSON_WITH_SCHEMA) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
// Fetch rows for specified view
|
// Fetch rows for specified view
|
||||||
$: fetchViewData(name, view.field, view.groupBy, view.calculation)
|
$: fetchViewData(name, view.field, view.groupBy, view.calculation)
|
||||||
|
@ -68,5 +77,5 @@
|
||||||
{/if}
|
{/if}
|
||||||
<ManageAccessButton resourceId={decodeURI(name)} />
|
<ManageAccessButton resourceId={decodeURI(name)} />
|
||||||
<HideAutocolumnButton bind:hideAutocolumns />
|
<HideAutocolumnButton bind:hideAutocolumns />
|
||||||
<ExportButton view={view.name} />
|
<ExportButton view={view.name} formats={supportedFormats} />
|
||||||
</Table>
|
</Table>
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
export let sorting
|
export let sorting
|
||||||
export let disabled = false
|
export let disabled = false
|
||||||
export let selectedRows
|
export let selectedRows
|
||||||
|
export let formats
|
||||||
|
|
||||||
let modal
|
let modal
|
||||||
</script>
|
</script>
|
||||||
|
@ -15,5 +16,5 @@
|
||||||
Export
|
Export
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
<Modal bind:this={modal}>
|
<Modal bind:this={modal}>
|
||||||
<ExportModal {view} {filters} {sorting} {selectedRows} />
|
<ExportModal {view} {filters} {sorting} {selectedRows} {formats} />
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -9,30 +9,43 @@
|
||||||
import download from "downloadjs"
|
import download from "downloadjs"
|
||||||
import { API } from "api"
|
import { API } from "api"
|
||||||
import { Constants, LuceneUtils } from "@budibase/frontend-core"
|
import { Constants, LuceneUtils } from "@budibase/frontend-core"
|
||||||
|
import { ROW_EXPORT_FORMATS } from "constants/backend"
|
||||||
const FORMATS = [
|
|
||||||
{
|
|
||||||
name: "CSV",
|
|
||||||
key: "csv",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "JSON",
|
|
||||||
key: "json",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "JSON with Schema",
|
|
||||||
key: "jsonWithSchema",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
export let view
|
export let view
|
||||||
export let filters
|
export let filters
|
||||||
export let sorting
|
export let sorting
|
||||||
export let selectedRows = []
|
export let selectedRows = []
|
||||||
|
export let formats
|
||||||
|
|
||||||
let exportFormat = FORMATS[0].key
|
const FORMATS = [
|
||||||
|
{
|
||||||
|
name: "CSV",
|
||||||
|
key: ROW_EXPORT_FORMATS.CSV,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "JSON",
|
||||||
|
key: ROW_EXPORT_FORMATS.JSON,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "JSON with Schema",
|
||||||
|
key: ROW_EXPORT_FORMATS.JSON_WITH_SCHEMA,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
$: options = FORMATS.filter(format => {
|
||||||
|
if (formats && !formats.includes(format.key)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
let exportFormat
|
||||||
let filterLookup
|
let filterLookup
|
||||||
|
|
||||||
|
$: if (options && !exportFormat) {
|
||||||
|
exportFormat = Array.isArray(options) ? options[0]?.key : []
|
||||||
|
}
|
||||||
|
|
||||||
$: luceneFilter = LuceneUtils.buildLuceneQuery(filters)
|
$: luceneFilter = LuceneUtils.buildLuceneQuery(filters)
|
||||||
$: exportOpDisplay = buildExportOpDisplay(sorting, filterDisplay, filters)
|
$: exportOpDisplay = buildExportOpDisplay(sorting, filterDisplay, filters)
|
||||||
|
|
||||||
|
@ -190,7 +203,7 @@
|
||||||
<Select
|
<Select
|
||||||
label="Format"
|
label="Format"
|
||||||
bind:value={exportFormat}
|
bind:value={exportFormat}
|
||||||
options={FORMATS}
|
{options}
|
||||||
placeholder={null}
|
placeholder={null}
|
||||||
getOptionLabel={x => x.name}
|
getOptionLabel={x => x.name}
|
||||||
getOptionValue={x => x.key}
|
getOptionValue={x => x.key}
|
||||||
|
|
|
@ -290,11 +290,11 @@
|
||||||
datasource.entities[getTable(toId).name].schema[toRelationship.name] =
|
datasource.entities[getTable(toId).name].schema[toRelationship.name] =
|
||||||
toRelationship
|
toRelationship
|
||||||
|
|
||||||
await save()
|
await save({ action: "saved" })
|
||||||
}
|
}
|
||||||
async function deleteRelationship() {
|
async function deleteRelationship() {
|
||||||
removeExistingRelationship()
|
removeExistingRelationship()
|
||||||
await save()
|
await save({ action: "deleted" })
|
||||||
await tables.fetch()
|
await tables.fetch()
|
||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// action is one of 'created', 'updated' or 'deleted'
|
// action is one of 'created', 'updated' or 'deleted'
|
||||||
async function saveRelationship(action) {
|
async function saveRelationship({ action }) {
|
||||||
try {
|
try {
|
||||||
await beforeSave({ action, datasource })
|
await beforeSave({ action, datasource })
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
let fieldList
|
let fieldList
|
||||||
let schema
|
let schema
|
||||||
let cachedValue
|
let cachedValue
|
||||||
|
let options
|
||||||
|
let sanitisedValue
|
||||||
|
let unconfigured
|
||||||
|
|
||||||
$: bindings = getBindableProperties($selectedScreen, componentInstance._id)
|
$: bindings = getBindableProperties($selectedScreen, componentInstance._id)
|
||||||
$: actionType = componentInstance.actionType
|
$: actionType = componentInstance.actionType
|
||||||
|
@ -34,16 +37,24 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
$: datasource = getDatasourceForProvider($currentAsset, componentInstance)
|
$: datasource = getDatasourceForProvider($currentAsset, componentInstance)
|
||||||
|
$: resourceId = datasource.resourceId || datasource.tableId
|
||||||
|
|
||||||
$: if (!isEqual(value, cachedValue)) {
|
$: if (!isEqual(value, cachedValue)) {
|
||||||
cachedValue = value
|
cachedValue = cloneDeep(value)
|
||||||
schema = getSchema($currentAsset, datasource)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$: options = Object.keys(schema || {})
|
const updateState = value => {
|
||||||
$: sanitisedValue = getValidColumns(convertOldFieldFormat(value), options)
|
schema = getSchema($currentAsset, datasource)
|
||||||
$: updateSanitsedFields(sanitisedValue)
|
options = Object.keys(schema || {})
|
||||||
$: unconfigured = buildUnconfiguredOptions(schema, sanitisedFields)
|
sanitisedValue = getValidColumns(convertOldFieldFormat(value), options)
|
||||||
|
updateSanitsedFields(sanitisedValue)
|
||||||
|
unconfigured = buildUnconfiguredOptions(schema, sanitisedFields)
|
||||||
|
fieldList = [...sanitisedFields, ...unconfigured]
|
||||||
|
.map(buildSudoInstance)
|
||||||
|
.filter(x => x != null)
|
||||||
|
}
|
||||||
|
|
||||||
|
$: updateState(cachedValue, resourceId)
|
||||||
|
|
||||||
// Builds unused ones only
|
// Builds unused ones only
|
||||||
const buildUnconfiguredOptions = (schema, selected) => {
|
const buildUnconfiguredOptions = (schema, selected) => {
|
||||||
|
@ -97,7 +108,6 @@
|
||||||
if (instance._component) {
|
if (instance._component) {
|
||||||
return instance
|
return instance
|
||||||
}
|
}
|
||||||
|
|
||||||
const type = getComponentForField(instance.field, schema)
|
const type = getComponentForField(instance.field, schema)
|
||||||
if (!type) {
|
if (!type) {
|
||||||
return null
|
return null
|
||||||
|
@ -118,12 +128,6 @@
|
||||||
return { ...instance, ...pseudoComponentInstance }
|
return { ...instance, ...pseudoComponentInstance }
|
||||||
}
|
}
|
||||||
|
|
||||||
$: if (sanitisedFields) {
|
|
||||||
fieldList = [...sanitisedFields, ...unconfigured]
|
|
||||||
.map(buildSudoInstance)
|
|
||||||
.filter(x => x != null)
|
|
||||||
}
|
|
||||||
|
|
||||||
const processItemUpdate = e => {
|
const processItemUpdate = e => {
|
||||||
const updatedField = e.detail
|
const updatedField = e.detail
|
||||||
const parentFieldsUpdated = fieldList ? cloneDeep(fieldList) : []
|
const parentFieldsUpdated = fieldList ? cloneDeep(fieldList) : []
|
||||||
|
|
|
@ -8,15 +8,16 @@
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
$: tables = $tablesStore.list.map(table => ({
|
$: tables = $tablesStore.list.map(table => ({
|
||||||
...table,
|
|
||||||
type: "table",
|
type: "table",
|
||||||
label: table.name,
|
label: table.name,
|
||||||
|
tableId: table._id,
|
||||||
resourceId: table._id,
|
resourceId: table._id,
|
||||||
}))
|
}))
|
||||||
$: views = $viewsV2.list.map(view => ({
|
$: views = $viewsV2.list.map(view => ({
|
||||||
...view,
|
|
||||||
type: "viewV2",
|
type: "viewV2",
|
||||||
|
id: view.id,
|
||||||
label: view.name,
|
label: view.name,
|
||||||
|
tableId: view.tableId,
|
||||||
resourceId: view.id,
|
resourceId: view.id,
|
||||||
}))
|
}))
|
||||||
$: options = [...(tables || []), ...(views || [])]
|
$: options = [...(tables || []), ...(views || [])]
|
||||||
|
@ -32,7 +33,7 @@
|
||||||
// Migrate old values before "resourceId" existed
|
// Migrate old values before "resourceId" existed
|
||||||
if (value && !value.resourceId) {
|
if (value && !value.resourceId) {
|
||||||
const view = views.find(x => x.resourceId === value.id)
|
const view = views.find(x => x.resourceId === value.id)
|
||||||
const table = tables.find(x => x.resourceId === value._id)
|
const table = tables.find(x => x.resourceId === value.tableId)
|
||||||
dispatch("change", view || table)
|
dispatch("change", view || table)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -287,3 +287,9 @@ export const DatasourceTypes = {
|
||||||
GRAPH: "Graph",
|
GRAPH: "Graph",
|
||||||
API: "API",
|
API: "API",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const ROW_EXPORT_FORMATS = {
|
||||||
|
CSV: "csv",
|
||||||
|
JSON: "json",
|
||||||
|
JSON_WITH_SCHEMA: "jsonWithSchema",
|
||||||
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@
|
||||||
await usersFetch.refresh()
|
await usersFetch.refresh()
|
||||||
|
|
||||||
filteredUsers = $usersFetch.rows
|
filteredUsers = $usersFetch.rows
|
||||||
.filter(user => !user?.admin?.global) // filter out global admins
|
.filter(user => user.email !== $auth.user.email)
|
||||||
.map(user => {
|
.map(user => {
|
||||||
const isAdminOrGlobalBuilder = sdk.users.isAdminOrGlobalBuilder(
|
const isAdminOrGlobalBuilder = sdk.users.isAdminOrGlobalBuilder(
|
||||||
user,
|
user,
|
||||||
|
@ -150,13 +150,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const sortInviteRoles = (a, b) => {
|
const sortInviteRoles = (a, b) => {
|
||||||
const aEmpty =
|
const aAppsEmpty = !a.info?.apps?.length && !a.info?.builder?.apps?.length
|
||||||
!a.info?.appBuilders?.length && Object.keys(a.info.apps).length === 0
|
const bAppsEmpty = !b.info?.apps?.length && !b.info?.builder?.apps?.length
|
||||||
const bEmpty =
|
|
||||||
!b.info?.appBuilders?.length && Object.keys(b.info.apps).length === 0
|
|
||||||
|
|
||||||
if (aEmpty && !bEmpty) return 1
|
return aAppsEmpty && !bAppsEmpty ? 1 : !aAppsEmpty && bAppsEmpty ? -1 : 0
|
||||||
if (!aEmpty && bEmpty) return -1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const sortRoles = (a, b) => {
|
const sortRoles = (a, b) => {
|
||||||
|
@ -366,18 +363,19 @@
|
||||||
const payload = [
|
const payload = [
|
||||||
{
|
{
|
||||||
email: newUserEmail,
|
email: newUserEmail,
|
||||||
builder: !!creationRoleType === Constants.BudibaseRoles.Admin,
|
builder: { global: creationRoleType === Constants.BudibaseRoles.Admin },
|
||||||
admin: !!creationRoleType === Constants.BudibaseRoles.Admin,
|
admin: { global: creationRoleType === Constants.BudibaseRoles.Admin },
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
if (creationAccessType === Constants.Roles.CREATOR) {
|
const notCreatingAdmin = creationRoleType !== Constants.BudibaseRoles.Admin
|
||||||
payload[0].appBuilders = [prodAppId]
|
const isCreator = creationAccessType === Constants.Roles.CREATOR
|
||||||
} else {
|
if (notCreatingAdmin && isCreator) {
|
||||||
payload[0].apps = {
|
payload[0].builder.apps = [prodAppId]
|
||||||
[prodAppId]: creationAccessType,
|
} else if (notCreatingAdmin && !isCreator) {
|
||||||
}
|
payload[0].apps = { [prodAppId]: creationAccessType }
|
||||||
}
|
}
|
||||||
|
|
||||||
let userInviteResponse
|
let userInviteResponse
|
||||||
try {
|
try {
|
||||||
userInviteResponse = await users.onboard(payload)
|
userInviteResponse = await users.onboard(payload)
|
||||||
|
@ -438,10 +436,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (role === Constants.Roles.CREATOR) {
|
if (role === Constants.Roles.CREATOR) {
|
||||||
updateBody.appBuilders = [...(updateBody.appBuilders ?? []), prodAppId]
|
updateBody.builder = updateBody.builder || {}
|
||||||
|
updateBody.builder.apps = [...(updateBody.builder.apps ?? []), prodAppId]
|
||||||
delete updateBody?.apps?.[prodAppId]
|
delete updateBody?.apps?.[prodAppId]
|
||||||
} else if (role !== Constants.Roles.CREATOR && invite?.appBuilders) {
|
} else if (role !== Constants.Roles.CREATOR && invite?.builder?.apps) {
|
||||||
invite.appBuilders = []
|
invite.builder.apps = []
|
||||||
}
|
}
|
||||||
await users.updateInvite(updateBody)
|
await users.updateInvite(updateBody)
|
||||||
await filterInvites(query)
|
await filterInvites(query)
|
||||||
|
@ -494,6 +493,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getInviteRoleValue = invite => {
|
||||||
|
if (invite.info?.admin?.global && invite.info?.builder?.global) {
|
||||||
|
return Constants.Roles.ADMIN
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invite.info?.builder?.apps?.includes(prodAppId)) {
|
||||||
|
return Constants.Roles.CREATOR
|
||||||
|
}
|
||||||
|
|
||||||
|
return invite.info.apps?.[prodAppId]
|
||||||
|
}
|
||||||
|
|
||||||
const getRoleFooter = user => {
|
const getRoleFooter = user => {
|
||||||
if (user.group) {
|
if (user.group) {
|
||||||
const role = $roles.find(role => role._id === user.role)
|
const role = $roles.find(role => role._id === user.role)
|
||||||
|
@ -531,7 +542,9 @@
|
||||||
<Heading size="S">{invitingFlow ? "Invite new user" : "Users"}</Heading>
|
<Heading size="S">{invitingFlow ? "Invite new user" : "Users"}</Heading>
|
||||||
</div>
|
</div>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<Button on:click={openInviteFlow} size="S" cta>Invite user</Button>
|
{#if !invitingFlow}
|
||||||
|
<Button on:click={openInviteFlow} size="S" cta>Invite user</Button>
|
||||||
|
{/if}
|
||||||
<Icon
|
<Icon
|
||||||
color="var(--spectrum-global-color-gray-600)"
|
color="var(--spectrum-global-color-gray-600)"
|
||||||
name="RailRightClose"
|
name="RailRightClose"
|
||||||
|
@ -600,6 +613,11 @@
|
||||||
<div class="auth-entity-access-title">Access</div>
|
<div class="auth-entity-access-title">Access</div>
|
||||||
</div>
|
</div>
|
||||||
{#each filteredInvites as invite}
|
{#each filteredInvites as invite}
|
||||||
|
{@const user = {
|
||||||
|
isAdminOrGlobalBuilder:
|
||||||
|
invite.info?.admin?.global && invite.info?.builder?.global,
|
||||||
|
}}
|
||||||
|
|
||||||
<div class="auth-entity">
|
<div class="auth-entity">
|
||||||
<div class="details">
|
<div class="details">
|
||||||
<div class="user-email" title={invite.email}>
|
<div class="user-email" title={invite.email}>
|
||||||
|
@ -608,10 +626,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="auth-entity-access">
|
<div class="auth-entity-access">
|
||||||
<RoleSelect
|
<RoleSelect
|
||||||
|
footer={getRoleFooter(user)}
|
||||||
placeholder={false}
|
placeholder={false}
|
||||||
value={invite.info?.appBuilders?.includes(prodAppId)
|
value={getInviteRoleValue(invite)}
|
||||||
? Constants.Roles.CREATOR
|
|
||||||
: invite.info.apps?.[prodAppId]}
|
|
||||||
allowRemove={invite.info.apps?.[prodAppId]}
|
allowRemove={invite.info.apps?.[prodAppId]}
|
||||||
allowPublic={false}
|
allowPublic={false}
|
||||||
allowCreator={true}
|
allowCreator={true}
|
||||||
|
@ -624,6 +641,9 @@
|
||||||
}}
|
}}
|
||||||
autoWidth
|
autoWidth
|
||||||
align="right"
|
align="right"
|
||||||
|
allowedRoles={user.isAdminOrGlobalBuilder
|
||||||
|
? [Constants.Roles.ADMIN]
|
||||||
|
: null}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -75,43 +75,37 @@
|
||||||
{@const views = Object.values(table.views || {}).filter(
|
{@const views = Object.values(table.views || {}).filter(
|
||||||
view => view.version === 2
|
view => view.version === 2
|
||||||
)}
|
)}
|
||||||
{@const datasource = {
|
{@const tableDS = {
|
||||||
...table,
|
|
||||||
// Legacy properties
|
|
||||||
tableId: table._id,
|
tableId: table._id,
|
||||||
label: table.name,
|
label: table.name,
|
||||||
// New consistent properties
|
|
||||||
resourceId: table._id,
|
resourceId: table._id,
|
||||||
name: table.name,
|
|
||||||
type: "table",
|
type: "table",
|
||||||
}}
|
}}
|
||||||
{@const selected = selectedScreens.find(
|
{@const selected = selectedScreens.find(
|
||||||
screen => screen.resourceId === datasource.resourceId
|
screen => screen.resourceId === tableDS.resourceId
|
||||||
)}
|
)}
|
||||||
<DatasourceTemplateRow
|
<DatasourceTemplateRow
|
||||||
on:click={() => toggleSelection(datasource)}
|
on:click={() => toggleSelection(tableDS)}
|
||||||
{selected}
|
{selected}
|
||||||
{datasource}
|
datasource={tableDS}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- List all views inside this table -->
|
<!-- List all views inside this table -->
|
||||||
{#each views as view}
|
{#each views as view}
|
||||||
{@const datasource = {
|
{@const viewDS = {
|
||||||
...view,
|
|
||||||
// Legacy properties
|
|
||||||
label: view.name,
|
label: view.name,
|
||||||
// New consistent properties
|
id: view.id,
|
||||||
resourceId: view.id,
|
resourceId: view.id,
|
||||||
name: view.name,
|
tableId: view.tableId,
|
||||||
type: "viewV2",
|
type: "viewV2",
|
||||||
}}
|
}}
|
||||||
{@const selected = selectedScreens.find(
|
{@const selected = selectedScreens.find(
|
||||||
x => x.resourceId === datasource.resourceId
|
x => x.resourceId === viewDS.resourceId
|
||||||
)}
|
)}
|
||||||
<DatasourceTemplateRow
|
<DatasourceTemplateRow
|
||||||
on:click={() => toggleSelection(datasource)}
|
on:click={() => toggleSelection(viewDS)}
|
||||||
{selected}
|
{selected}
|
||||||
{datasource}
|
datasource={viewDS}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
{/each}
|
{/each}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
<div class="data-source-entry" class:selected on:click>
|
<div class="data-source-entry" class:selected on:click>
|
||||||
<Icon name={icon} color="var(--spectrum-global-color-gray-600)" />
|
<Icon name={icon} color="var(--spectrum-global-color-gray-600)" />
|
||||||
{datasource.name}
|
{datasource.label}
|
||||||
{#if selected}
|
{#if selected}
|
||||||
<span class="data-source-check">
|
<span class="data-source-check">
|
||||||
<Icon size="S" name="CheckmarkCircle" />
|
<Icon size="S" name="CheckmarkCircle" />
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
|
|
||||||
let loaded = false
|
let loaded = false
|
||||||
let editModal, deleteModal
|
let editModal, deleteModal
|
||||||
$: console.log(group)
|
|
||||||
$: scimEnabled = $features.isScimEnabled
|
$: scimEnabled = $features.isScimEnabled
|
||||||
$: readonly = !sdk.users.isAdmin($auth.user) || scimEnabled
|
$: readonly = !sdk.users.isAdmin($auth.user) || scimEnabled
|
||||||
$: group = $groups.find(x => x._id === groupId)
|
$: group = $groups.find(x => x._id === groupId)
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
? Constants.Roles.CREATOR
|
? Constants.Roles.CREATOR
|
||||||
: group?.roles?.[apps.getProdAppID(app.devId)],
|
: group?.roles?.[apps.getProdAppID(app.devId)],
|
||||||
}))
|
}))
|
||||||
$: console.log(groupApps)
|
|
||||||
$: {
|
$: {
|
||||||
if (loaded && !group?._id) {
|
if (loaded && !group?._id) {
|
||||||
$goto("./")
|
$goto("./")
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
export let value
|
export let value
|
||||||
export let row
|
export let row
|
||||||
$: console.log(row)
|
|
||||||
$: priviliged = sdk.users.isAdminOrBuilder(row)
|
$: priviliged = sdk.users.isAdminOrBuilder(row)
|
||||||
$: count = getCount(row)
|
$: count = getCount(row)
|
||||||
|
|
||||||
|
@ -14,10 +13,10 @@
|
||||||
return $apps.length
|
return $apps.length
|
||||||
} else {
|
} else {
|
||||||
return sdk.users.hasAppBuilderPermissions(row)
|
return sdk.users.hasAppBuilderPermissions(row)
|
||||||
? row.builder.apps.length +
|
? row?.builder?.apps?.length +
|
||||||
Object.keys(row.roles || {}).filter(appId =>
|
Object.keys(row.roles || {}).filter(appId => {
|
||||||
row.builder.apps.includes(appId)
|
row?.builder?.apps?.includes(appId)
|
||||||
).length
|
}).length
|
||||||
: value?.length || 0
|
: value?.length || 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
admin: "Full access",
|
admin: "Full access",
|
||||||
}
|
}
|
||||||
|
|
||||||
$: role = Constants.BudibaseRoleOptions.find(
|
$: role = Constants.BudibaseRoleOptionsOld.find(
|
||||||
x => x.value === users.getUserRole(row)
|
x => x.value === users.getUserRole(row)
|
||||||
)
|
)
|
||||||
$: value = role?.label || "Not available"
|
$: value = role?.label || "Not available"
|
||||||
|
|
|
@ -121,8 +121,11 @@ export function createUsersStore() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const getUserRole = user =>
|
const getUserRole = user =>
|
||||||
sdk.users.isAdminOrGlobalBuilder(user) ? "admin" : "appUser"
|
sdk.users.isAdmin(user)
|
||||||
|
? "admin"
|
||||||
|
: sdk.users.isBuilder(user)
|
||||||
|
? "developer"
|
||||||
|
: "appUser"
|
||||||
const refreshUsage =
|
const refreshUsage =
|
||||||
fn =>
|
fn =>
|
||||||
async (...args) => {
|
async (...args) => {
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
"@swc/core": "1.3.71",
|
"@swc/core": "1.3.71",
|
||||||
"@swc/jest": "0.2.27",
|
"@swc/jest": "0.2.27",
|
||||||
"@types/jest": "29.5.3",
|
"@types/jest": "29.5.3",
|
||||||
"@types/node-fetch": "2.6.1",
|
"@types/node-fetch": "2.6.4",
|
||||||
"@types/pouchdb": "^6.4.0",
|
"@types/pouchdb": "^6.4.0",
|
||||||
"copyfiles": "^2.4.1",
|
"copyfiles": "^2.4.1",
|
||||||
"eslint": "^7.20.0",
|
"eslint": "^7.20.0",
|
||||||
|
|
|
@ -3647,9 +3647,9 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"label": "Autocomplete",
|
"label": "Search",
|
||||||
"key": "autocomplete",
|
"key": "autocomplete",
|
||||||
"defaultValue": false
|
"defaultValue": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
@ -4745,7 +4745,8 @@
|
||||||
"dependsOn": {
|
"dependsOn": {
|
||||||
"setting": "clickBehaviour",
|
"setting": "clickBehaviour",
|
||||||
"value": "details"
|
"value": "details"
|
||||||
}
|
},
|
||||||
|
"resetOn": "dataSource"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Save button",
|
"label": "Save button",
|
||||||
|
@ -5397,6 +5398,7 @@
|
||||||
"type": "fieldConfiguration",
|
"type": "fieldConfiguration",
|
||||||
"key": "fields",
|
"key": "fields",
|
||||||
"nested": true,
|
"nested": true,
|
||||||
|
"resetOn": "dataSource",
|
||||||
"selectAllFields": true
|
"selectAllFields": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
themeStore,
|
themeStore,
|
||||||
appStore,
|
appStore,
|
||||||
devToolsStore,
|
devToolsStore,
|
||||||
environmentStore,
|
|
||||||
devToolsEnabled,
|
devToolsEnabled,
|
||||||
} from "stores"
|
} from "stores"
|
||||||
import NotificationDisplay from "components/overlay/NotificationDisplay.svelte"
|
import NotificationDisplay from "components/overlay/NotificationDisplay.svelte"
|
||||||
|
@ -206,7 +205,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if !$builderStore.inBuilder && licensing.logoEnabled() && $environmentStore.cloud}
|
{#if !$builderStore.inBuilder && licensing.logoEnabled()}
|
||||||
<FreeFooter />
|
<FreeFooter />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -275,7 +275,7 @@
|
||||||
dataSource,
|
dataSource,
|
||||||
showSaveButton: true,
|
showSaveButton: true,
|
||||||
showDeleteButton: false,
|
showDeleteButton: false,
|
||||||
saveButtonLabel: sidePanelSaveLabel,
|
saveButtonLabel: sidePanelSaveLabel || "Save", //always show
|
||||||
actionType: "Create",
|
actionType: "Create",
|
||||||
fields: sidePanelFields || normalFields,
|
fields: sidePanelFields || normalFields,
|
||||||
title: "Create Row",
|
title: "Create Row",
|
||||||
|
|
|
@ -211,17 +211,19 @@
|
||||||
{/if}
|
{/if}
|
||||||
</BlockComponent>
|
</BlockComponent>
|
||||||
{/if}
|
{/if}
|
||||||
<BlockComponent type="fieldgroup" props={{ labelPosition }} order={1}>
|
{#key fields}
|
||||||
{#each fields as field, idx}
|
<BlockComponent type="fieldgroup" props={{ labelPosition }} order={1}>
|
||||||
{#if getComponentForField(field) && field.active}
|
{#each fields as field, idx}
|
||||||
<BlockComponent
|
{#if getComponentForField(field) && field.active}
|
||||||
type={getComponentForField(field)}
|
<BlockComponent
|
||||||
props={getPropsForField(field)}
|
type={getComponentForField(field)}
|
||||||
order={idx}
|
props={getPropsForField(field)}
|
||||||
/>
|
order={idx}
|
||||||
{/if}
|
/>
|
||||||
{/each}
|
{/if}
|
||||||
</BlockComponent>
|
{/each}
|
||||||
|
</BlockComponent>
|
||||||
|
{/key}
|
||||||
</BlockComponent>
|
</BlockComponent>
|
||||||
</BlockComponent>
|
</BlockComponent>
|
||||||
{:else}
|
{:else}
|
||||||
|
|
|
@ -136,7 +136,7 @@
|
||||||
// Check arrays - remove any values not present in the field schema and
|
// Check arrays - remove any values not present in the field schema and
|
||||||
// convert any values supplied to strings
|
// convert any values supplied to strings
|
||||||
if (Array.isArray(value) && type === "array" && schema) {
|
if (Array.isArray(value) && type === "array" && schema) {
|
||||||
const options = schema?.constraints.inclusion || []
|
const options = schema?.constraints?.inclusion || []
|
||||||
return value.map(opt => String(opt)).filter(opt => options.includes(opt))
|
return value.map(opt => String(opt)).filter(opt => options.includes(opt))
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
<script>
|
<script>
|
||||||
import { CoreSelect, CoreMultiselect } from "@budibase/bbui"
|
import {
|
||||||
import { fetchData } from "@budibase/frontend-core"
|
CoreSelect,
|
||||||
|
CoreMultiselect,
|
||||||
|
Input,
|
||||||
|
ProgressCircle,
|
||||||
|
} from "@budibase/bbui"
|
||||||
|
import { fetchData, Utils } from "@budibase/frontend-core"
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import Field from "./Field.svelte"
|
import Field from "./Field.svelte"
|
||||||
import { FieldTypes } from "../../../constants"
|
import { FieldTypes } from "../../../constants"
|
||||||
|
@ -12,7 +17,7 @@
|
||||||
export let placeholder
|
export let placeholder
|
||||||
export let disabled = false
|
export let disabled = false
|
||||||
export let validation
|
export let validation
|
||||||
export let autocomplete = false
|
export let autocomplete = true
|
||||||
export let defaultValue
|
export let defaultValue
|
||||||
export let onChange
|
export let onChange
|
||||||
export let filter
|
export let filter
|
||||||
|
@ -21,6 +26,16 @@
|
||||||
let fieldApi
|
let fieldApi
|
||||||
let fieldSchema
|
let fieldSchema
|
||||||
let tableDefinition
|
let tableDefinition
|
||||||
|
let primaryDisplay
|
||||||
|
let options
|
||||||
|
let selectedOptions = []
|
||||||
|
let isOpen = false
|
||||||
|
let hasFilter
|
||||||
|
|
||||||
|
let searchResults
|
||||||
|
let searchString
|
||||||
|
let searching = false
|
||||||
|
let lastSearchId
|
||||||
|
|
||||||
$: multiselect = fieldSchema?.relationshipType !== "one-to-many"
|
$: multiselect = fieldSchema?.relationshipType !== "one-to-many"
|
||||||
$: linkedTableId = fieldSchema?.tableId
|
$: linkedTableId = fieldSchema?.tableId
|
||||||
|
@ -35,13 +50,57 @@
|
||||||
limit: 100,
|
limit: 100,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
$: hasFilter = !!filter?.filter(f => !!f.field)?.length
|
||||||
$: fetch.update({ filter })
|
$: fetch.update({ filter })
|
||||||
$: options = $fetch.rows
|
$: {
|
||||||
|
options = searchResults ? searchResults : $fetch.rows
|
||||||
|
const nonMatchingOptions = selectedOptions.filter(
|
||||||
|
option => !options.map(opt => opt._id).includes(option._id)
|
||||||
|
)
|
||||||
|
// Append initially selected options if there is no filter
|
||||||
|
// and hasn't already been appended
|
||||||
|
if (!hasFilter) {
|
||||||
|
options = [...options, ...nonMatchingOptions]
|
||||||
|
}
|
||||||
|
}
|
||||||
$: tableDefinition = $fetch.definition
|
$: tableDefinition = $fetch.definition
|
||||||
|
$: primaryDisplay = tableDefinition?.primaryDisplay || "_id"
|
||||||
$: singleValue = flatten(fieldState?.value)?.[0]
|
$: singleValue = flatten(fieldState?.value)?.[0]
|
||||||
$: multiValue = flatten(fieldState?.value) ?? []
|
$: multiValue = flatten(fieldState?.value) ?? []
|
||||||
$: component = multiselect ? CoreMultiselect : CoreSelect
|
$: component = multiselect ? CoreMultiselect : CoreSelect
|
||||||
$: expandedDefaultValue = expand(defaultValue)
|
$: expandedDefaultValue = expand(defaultValue)
|
||||||
|
$: debouncedSearch(searchString)
|
||||||
|
$: {
|
||||||
|
if (searching) {
|
||||||
|
isOpen = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch the initially selected values
|
||||||
|
// as they may not be within the first 100 records
|
||||||
|
$: {
|
||||||
|
if (
|
||||||
|
primaryDisplay !== "_id" &&
|
||||||
|
fieldState?.value?.length &&
|
||||||
|
!selectedOptions?.length
|
||||||
|
) {
|
||||||
|
API.searchTable({
|
||||||
|
paginate: false,
|
||||||
|
tableId: linkedTableId,
|
||||||
|
limit: 100,
|
||||||
|
query: {
|
||||||
|
oneOf: {
|
||||||
|
[`1:${primaryDisplay}`]: fieldState?.value?.map(
|
||||||
|
value => value.primaryDisplay
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}).then(response => {
|
||||||
|
const value = multiselect ? multiValue : singleValue
|
||||||
|
selectedOptions = response.rows.filter(row => value.includes(row._id))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const flatten = values => {
|
const flatten = values => {
|
||||||
if (!values) {
|
if (!values) {
|
||||||
|
@ -77,10 +136,66 @@
|
||||||
|
|
||||||
const handleChange = value => {
|
const handleChange = value => {
|
||||||
const changed = fieldApi.setValue(value)
|
const changed = fieldApi.setValue(value)
|
||||||
|
selectedOptions = value.map(val => ({
|
||||||
|
_id: val,
|
||||||
|
[primaryDisplay]: options.find(option => option._id === val)[
|
||||||
|
primaryDisplay
|
||||||
|
],
|
||||||
|
}))
|
||||||
if (onChange && changed) {
|
if (onChange && changed) {
|
||||||
onChange({ value })
|
onChange({ value })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Search for rows based on the search string
|
||||||
|
const search = async searchString => {
|
||||||
|
// Reset state if this search is invalid
|
||||||
|
if (!linkedTableId || !searchString) {
|
||||||
|
searchResults = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a filter exists, then do a client side search
|
||||||
|
if (hasFilter) {
|
||||||
|
searchResults = $fetch.rows.filter(option =>
|
||||||
|
option[primaryDisplay].startsWith(searchString)
|
||||||
|
)
|
||||||
|
isOpen = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for results, using IDs to track invocations and ensure we're
|
||||||
|
// handling the latest update
|
||||||
|
lastSearchId = Math.random()
|
||||||
|
searching = true
|
||||||
|
const thisSearchId = lastSearchId
|
||||||
|
const results = await API.searchTable({
|
||||||
|
paginate: false,
|
||||||
|
tableId: linkedTableId,
|
||||||
|
limit: 100,
|
||||||
|
query: {
|
||||||
|
string: {
|
||||||
|
[`1:${primaryDisplay}`]: searchString || "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
searching = false
|
||||||
|
|
||||||
|
// In case searching takes longer than our debounced update, abandon these
|
||||||
|
// results
|
||||||
|
if (thisSearchId !== lastSearchId) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process results
|
||||||
|
searchResults = results.rows?.map(row => ({
|
||||||
|
...row,
|
||||||
|
primaryDisplay: row[primaryDisplay],
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debounced version of searching
|
||||||
|
const debouncedSearch = Utils.debounce(search, 250)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Field
|
<Field
|
||||||
|
@ -95,19 +210,63 @@
|
||||||
bind:fieldSchema
|
bind:fieldSchema
|
||||||
>
|
>
|
||||||
{#if fieldState}
|
{#if fieldState}
|
||||||
<svelte:component
|
<div class={autocomplete ? "field-with-search" : ""}>
|
||||||
this={component}
|
<svelte:component
|
||||||
{options}
|
this={component}
|
||||||
{autocomplete}
|
bind:open={isOpen}
|
||||||
value={multiselect ? multiValue : singleValue}
|
{options}
|
||||||
on:change={multiselect ? multiHandler : singleHandler}
|
autocomplete={false}
|
||||||
id={fieldState.fieldId}
|
value={multiselect ? multiValue : singleValue}
|
||||||
disabled={fieldState.disabled}
|
on:change={multiselect ? multiHandler : singleHandler}
|
||||||
error={fieldState.error}
|
id={fieldState.fieldId}
|
||||||
getOptionLabel={getDisplayName}
|
disabled={fieldState.disabled}
|
||||||
getOptionValue={option => option._id}
|
error={fieldState.error}
|
||||||
{placeholder}
|
getOptionLabel={getDisplayName}
|
||||||
sort={true}
|
getOptionValue={option => option._id}
|
||||||
/>
|
{placeholder}
|
||||||
|
customPopoverOffsetBelow={autocomplete ? 32 : null}
|
||||||
|
customPopoverMaxHeight={autocomplete ? 240 : null}
|
||||||
|
sort={true}
|
||||||
|
/>
|
||||||
|
{#if autocomplete}
|
||||||
|
<div class="search">
|
||||||
|
<Input
|
||||||
|
autofocus
|
||||||
|
quiet
|
||||||
|
type="text"
|
||||||
|
bind:value={searchString}
|
||||||
|
placeholder={primaryDisplay ? `Search by ${primaryDisplay}` : null}
|
||||||
|
/>
|
||||||
|
{#if searching}
|
||||||
|
<div>
|
||||||
|
<ProgressCircle size="S" />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</Field>
|
</Field>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.search {
|
||||||
|
flex: 0 0 calc(var(--default-row-height) - 1px);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 4px var(--cell-padding);
|
||||||
|
width: calc(100% - 2 * var(--cell-padding));
|
||||||
|
}
|
||||||
|
.search :global(.spectrum-Textfield) {
|
||||||
|
min-width: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.search :global(.spectrum-Textfield-input) {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.search :global(.spectrum-Form-item) {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
.field-with-search {
|
||||||
|
min-height: 80px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -144,8 +144,8 @@ export const buildUserEndpoints = API => ({
|
||||||
body: {
|
body: {
|
||||||
email,
|
email,
|
||||||
userInfo: {
|
userInfo: {
|
||||||
admin: admin ? { global: true } : undefined,
|
admin: admin?.global ? { global: true } : undefined,
|
||||||
builder: builder ? { global: true } : undefined,
|
builder: builder?.global ? { global: true } : undefined,
|
||||||
apps: apps ? apps : undefined,
|
apps: apps ? apps : undefined,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -156,14 +156,13 @@ export const buildUserEndpoints = API => ({
|
||||||
return await API.post({
|
return await API.post({
|
||||||
url: "/api/global/users/onboard",
|
url: "/api/global/users/onboard",
|
||||||
body: payload.map(invite => {
|
body: payload.map(invite => {
|
||||||
const { email, admin, builder, apps, appBuilders } = invite
|
const { email, admin, builder, apps } = invite
|
||||||
return {
|
return {
|
||||||
email,
|
email,
|
||||||
userInfo: {
|
userInfo: {
|
||||||
admin: admin ? { global: true } : undefined,
|
admin,
|
||||||
builder: builder ? { global: true } : undefined,
|
builder,
|
||||||
apps: apps ? apps : undefined,
|
apps: apps ? apps : undefined,
|
||||||
appBuilders,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
@ -176,12 +175,11 @@ export const buildUserEndpoints = API => ({
|
||||||
* @param invite the invite code sent in the email
|
* @param invite the invite code sent in the email
|
||||||
*/
|
*/
|
||||||
updateUserInvite: async invite => {
|
updateUserInvite: async invite => {
|
||||||
console.log(invite)
|
|
||||||
await API.post({
|
await API.post({
|
||||||
url: `/api/global/users/invite/update/${invite.code}`,
|
url: `/api/global/users/invite/update/${invite.code}`,
|
||||||
body: {
|
body: {
|
||||||
apps: invite.apps,
|
apps: invite.apps,
|
||||||
appBuilders: invite.appBuilders,
|
builder: invite.builder,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,6 +23,11 @@ export const BudibaseRoles = {
|
||||||
Admin: "admin",
|
Admin: "admin",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const BudibaseRoleOptionsOld = [
|
||||||
|
{ label: "Developer", value: BudibaseRoles.Developer },
|
||||||
|
{ label: "Member", value: BudibaseRoles.AppUser },
|
||||||
|
{ label: "Admin", value: BudibaseRoles.Admin },
|
||||||
|
]
|
||||||
export const BudibaseRoleOptions = [
|
export const BudibaseRoleOptions = [
|
||||||
{ label: "Member", value: BudibaseRoles.AppUser },
|
{ label: "Member", value: BudibaseRoles.AppUser },
|
||||||
{ label: "Admin", value: BudibaseRoles.Admin },
|
{ label: "Admin", value: BudibaseRoles.Admin },
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
export { createAPIClient } from "./api"
|
export { createAPIClient } from "./api"
|
||||||
export { fetchData } from "./fetch/fetchData"
|
export { fetchData } from "./fetch/fetchData"
|
||||||
|
export { Utils } from "./utils"
|
||||||
export * as Constants from "./constants"
|
export * as Constants from "./constants"
|
||||||
export * from "./stores"
|
export * from "./stores"
|
||||||
export * from "./utils"
|
export * from "./utils"
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 140386c7ad7e3d50bd361fc702e49b288c1747c2
|
Subproject commit 4638ae916e55ce89166095578cbd01745d0ee9ee
|
|
@ -26,7 +26,7 @@
|
||||||
"dev:stack:up": "node scripts/dev/manage.js up",
|
"dev:stack:up": "node scripts/dev/manage.js up",
|
||||||
"dev:stack:down": "node scripts/dev/manage.js down",
|
"dev:stack:down": "node scripts/dev/manage.js down",
|
||||||
"dev:stack:nuke": "node scripts/dev/manage.js nuke",
|
"dev:stack:nuke": "node scripts/dev/manage.js nuke",
|
||||||
"dev:builder": "yarn run dev:stack:up && rimraf dist/ && nodemon",
|
"dev:builder": "yarn run dev:stack:up && nodemon",
|
||||||
"dev:built": "yarn run dev:stack:up && yarn run run:docker",
|
"dev:built": "yarn run dev:stack:up && yarn run run:docker",
|
||||||
"specs": "ts-node specs/generate.ts && openapi-typescript specs/openapi.yaml --output src/definitions/openapi.ts",
|
"specs": "ts-node specs/generate.ts && openapi-typescript specs/openapi.yaml --output src/definitions/openapi.ts",
|
||||||
"initialise": "node scripts/initialise.js",
|
"initialise": "node scripts/initialise.js",
|
||||||
|
@ -144,8 +144,8 @@
|
||||||
"@types/koa__router": "8.0.8",
|
"@types/koa__router": "8.0.8",
|
||||||
"@types/lodash": "4.14.180",
|
"@types/lodash": "4.14.180",
|
||||||
"@types/mssql": "8.1.2",
|
"@types/mssql": "8.1.2",
|
||||||
"@types/node": "14.18.20",
|
"@types/node": "18.17.0",
|
||||||
"@types/node-fetch": "2.6.1",
|
"@types/node-fetch": "2.6.4",
|
||||||
"@types/oracledb": "5.2.2",
|
"@types/oracledb": "5.2.2",
|
||||||
"@types/pg": "8.6.6",
|
"@types/pg": "8.6.6",
|
||||||
"@types/pouchdb": "6.4.0",
|
"@types/pouchdb": "6.4.0",
|
||||||
|
|
|
@ -39,8 +39,9 @@ import {
|
||||||
} from "../../db/defaultData/datasource_bb_default"
|
} from "../../db/defaultData/datasource_bb_default"
|
||||||
import { removeAppFromUserRoles } from "../../utilities/workerRequests"
|
import { removeAppFromUserRoles } from "../../utilities/workerRequests"
|
||||||
import { stringToReadStream } from "../../utilities"
|
import { stringToReadStream } from "../../utilities"
|
||||||
import { doesUserHaveLock } from "../../utilities/redis"
|
import { doesUserHaveLock, getLocksById } from "../../utilities/redis"
|
||||||
import { cleanupAutomations } from "../../automations/utils"
|
import { cleanupAutomations } from "../../automations/utils"
|
||||||
|
import { checkAppMetadata } from "../../automations/logging"
|
||||||
import { getUniqueRows } from "../../utilities/usageQuota/rows"
|
import { getUniqueRows } from "../../utilities/usageQuota/rows"
|
||||||
import { groups, licensing, quotas } from "@budibase/pro"
|
import { groups, licensing, quotas } from "@budibase/pro"
|
||||||
import {
|
import {
|
||||||
|
@ -50,6 +51,7 @@ import {
|
||||||
PlanType,
|
PlanType,
|
||||||
Screen,
|
Screen,
|
||||||
UserCtx,
|
UserCtx,
|
||||||
|
ContextUser,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { BASE_LAYOUT_PROP_IDS } from "../../constants/layouts"
|
import { BASE_LAYOUT_PROP_IDS } from "../../constants/layouts"
|
||||||
import sdk from "../../sdk"
|
import sdk from "../../sdk"
|
||||||
|
|
|
@ -20,7 +20,7 @@ import {
|
||||||
Automation,
|
Automation,
|
||||||
AutomationActionStepId,
|
AutomationActionStepId,
|
||||||
AutomationResults,
|
AutomationResults,
|
||||||
Ctx,
|
BBContext,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { getActionDefinitions as actionDefs } from "../../automations/actions"
|
import { getActionDefinitions as actionDefs } from "../../automations/actions"
|
||||||
import sdk from "../../sdk"
|
import sdk from "../../sdk"
|
||||||
|
@ -73,7 +73,7 @@ function cleanAutomationInputs(automation: Automation) {
|
||||||
return automation
|
return automation
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function create(ctx: Ctx) {
|
export async function create(ctx: BBContext) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
let automation = ctx.request.body
|
let automation = ctx.request.body
|
||||||
automation.appId = ctx.appId
|
automation.appId = ctx.appId
|
||||||
|
@ -142,7 +142,7 @@ export async function handleStepEvents(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function update(ctx: Ctx) {
|
export async function update(ctx: BBContext) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
let automation = ctx.request.body
|
let automation = ctx.request.body
|
||||||
automation.appId = ctx.appId
|
automation.appId = ctx.appId
|
||||||
|
@ -193,7 +193,7 @@ export async function update(ctx: Ctx) {
|
||||||
builderSocket?.emitAutomationUpdate(ctx, automation)
|
builderSocket?.emitAutomationUpdate(ctx, automation)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetch(ctx: Ctx) {
|
export async function fetch(ctx: BBContext) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
const response = await db.allDocs(
|
const response = await db.allDocs(
|
||||||
getAutomationParams(null, {
|
getAutomationParams(null, {
|
||||||
|
@ -203,11 +203,12 @@ export async function fetch(ctx: Ctx) {
|
||||||
ctx.body = response.rows.map(row => row.doc)
|
ctx.body = response.rows.map(row => row.doc)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function find(ctx: Ctx) {
|
export async function find(ctx: BBContext) {
|
||||||
ctx.body = await sdk.automations.get(ctx.params.id)
|
const db = context.getAppDB()
|
||||||
|
ctx.body = await db.get(ctx.params.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function destroy(ctx: Ctx) {
|
export async function destroy(ctx: BBContext) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
const automationId = ctx.params.id
|
const automationId = ctx.params.id
|
||||||
const oldAutomation = await db.get<Automation>(automationId)
|
const oldAutomation = await db.get<Automation>(automationId)
|
||||||
|
@ -221,11 +222,11 @@ export async function destroy(ctx: Ctx) {
|
||||||
builderSocket?.emitAutomationDeletion(ctx, automationId)
|
builderSocket?.emitAutomationDeletion(ctx, automationId)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function logSearch(ctx: Ctx) {
|
export async function logSearch(ctx: BBContext) {
|
||||||
ctx.body = await automations.logs.logSearch(ctx.request.body)
|
ctx.body = await automations.logs.logSearch(ctx.request.body)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function clearLogError(ctx: Ctx) {
|
export async function clearLogError(ctx: BBContext) {
|
||||||
const { automationId, appId } = ctx.request.body
|
const { automationId, appId } = ctx.request.body
|
||||||
await context.doInAppContext(appId, async () => {
|
await context.doInAppContext(appId, async () => {
|
||||||
const db = context.getProdAppDB()
|
const db = context.getProdAppDB()
|
||||||
|
@ -244,15 +245,15 @@ export async function clearLogError(ctx: Ctx) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getActionList(ctx: Ctx) {
|
export async function getActionList(ctx: BBContext) {
|
||||||
ctx.body = await getActionDefinitions()
|
ctx.body = await getActionDefinitions()
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getTriggerList(ctx: Ctx) {
|
export async function getTriggerList(ctx: BBContext) {
|
||||||
ctx.body = getTriggerDefinitions()
|
ctx.body = getTriggerDefinitions()
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDefinitionList(ctx: Ctx) {
|
export async function getDefinitionList(ctx: BBContext) {
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
trigger: getTriggerDefinitions(),
|
trigger: getTriggerDefinitions(),
|
||||||
action: await getActionDefinitions(),
|
action: await getActionDefinitions(),
|
||||||
|
@ -265,7 +266,7 @@ export async function getDefinitionList(ctx: Ctx) {
|
||||||
* *
|
* *
|
||||||
*********************/
|
*********************/
|
||||||
|
|
||||||
export async function trigger(ctx: Ctx) {
|
export async function trigger(ctx: BBContext) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
let automation = await db.get<Automation>(ctx.params.id)
|
let automation = await db.get<Automation>(ctx.params.id)
|
||||||
|
|
||||||
|
@ -310,7 +311,7 @@ function prepareTestInput(input: any) {
|
||||||
return input
|
return input
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function test(ctx: Ctx) {
|
export async function test(ctx: BBContext) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
let automation = await db.get<Automation>(ctx.params.id)
|
let automation = await db.get<Automation>(ctx.params.id)
|
||||||
await setTestFlag(automation._id!)
|
await setTestFlag(automation._id!)
|
||||||
|
|
|
@ -95,7 +95,7 @@ export async function fetchView(ctx: any) {
|
||||||
() =>
|
() =>
|
||||||
sdk.rows.fetchView(tableId, viewName, {
|
sdk.rows.fetchView(tableId, viewName, {
|
||||||
calculation,
|
calculation,
|
||||||
group,
|
group: calculation ? group : null,
|
||||||
field,
|
field,
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,7 +27,7 @@ export function json(rows: Row[]) {
|
||||||
export function jsonWithSchema(schema: TableSchema, rows: Row[]) {
|
export function jsonWithSchema(schema: TableSchema, rows: Row[]) {
|
||||||
const newSchema: TableSchema = {}
|
const newSchema: TableSchema = {}
|
||||||
Object.values(schema).forEach(column => {
|
Object.values(schema).forEach(column => {
|
||||||
if (!column.autocolumn) {
|
if (!column.autocolumn && column.name) {
|
||||||
newSchema[column.name] = column
|
newSchema[column.name] = column
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,12 +3,13 @@ import { databaseTestProviders } from "../../../integrations/tests/utils"
|
||||||
import tk from "timekeeper"
|
import tk from "timekeeper"
|
||||||
import { outputProcessing } from "../../../utilities/rowProcessor"
|
import { outputProcessing } from "../../../utilities/rowProcessor"
|
||||||
import * as setup from "./utilities"
|
import * as setup from "./utilities"
|
||||||
import { context, tenancy } from "@budibase/backend-core"
|
import { context, roles, tenancy } from "@budibase/backend-core"
|
||||||
import { quotas } from "@budibase/pro"
|
import { quotas } from "@budibase/pro"
|
||||||
import {
|
import {
|
||||||
Datasource,
|
Datasource,
|
||||||
FieldType,
|
FieldType,
|
||||||
MonthlyQuotaName,
|
MonthlyQuotaName,
|
||||||
|
PermissionLevel,
|
||||||
QuotaUsageType,
|
QuotaUsageType,
|
||||||
Row,
|
Row,
|
||||||
SaveTableRequest,
|
SaveTableRequest,
|
||||||
|
@ -20,6 +21,7 @@ import {
|
||||||
import {
|
import {
|
||||||
expectAnyInternalColsAttributes,
|
expectAnyInternalColsAttributes,
|
||||||
generator,
|
generator,
|
||||||
|
mocks,
|
||||||
structures,
|
structures,
|
||||||
} from "@budibase/backend-core/tests"
|
} from "@budibase/backend-core/tests"
|
||||||
|
|
||||||
|
@ -45,6 +47,7 @@ describe.each([
|
||||||
})
|
})
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
mocks.licenses.useCloudFree()
|
||||||
let tableConfig: SaveTableRequest = {
|
let tableConfig: SaveTableRequest = {
|
||||||
name: generator.guid(),
|
name: generator.guid(),
|
||||||
type: "table",
|
type: "table",
|
||||||
|
@ -1365,6 +1368,85 @@ describe.each([
|
||||||
bookmark: expect.any(String),
|
bookmark: expect.any(String),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("permissions", () => {
|
||||||
|
let viewId: string
|
||||||
|
let tableId: string
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const table = await config.createTable(userTable())
|
||||||
|
const rows = []
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
rows.push(await config.createRow({ tableId: table._id }))
|
||||||
|
}
|
||||||
|
|
||||||
|
const createViewResponse = await config.api.viewV2.create()
|
||||||
|
|
||||||
|
tableId = table._id!
|
||||||
|
viewId = createViewResponse.id
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
mocks.licenses.useViewPermissions()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("does not allow public users to fetch by default", async () => {
|
||||||
|
await config.publish()
|
||||||
|
await config.api.viewV2.search(viewId, undefined, {
|
||||||
|
expectStatus: 403,
|
||||||
|
usePublicUser: true,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("allow public users to fetch when permissions are explicit", async () => {
|
||||||
|
await config.api.permission.set({
|
||||||
|
roleId: roles.BUILTIN_ROLE_IDS.PUBLIC,
|
||||||
|
level: PermissionLevel.READ,
|
||||||
|
resourceId: viewId,
|
||||||
|
})
|
||||||
|
await config.publish()
|
||||||
|
|
||||||
|
const response = await config.api.viewV2.search(viewId, undefined, {
|
||||||
|
usePublicUser: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(response.body.rows).toHaveLength(10)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("allow public users to fetch when permissions are inherited", async () => {
|
||||||
|
await config.api.permission.set({
|
||||||
|
roleId: roles.BUILTIN_ROLE_IDS.PUBLIC,
|
||||||
|
level: PermissionLevel.READ,
|
||||||
|
resourceId: tableId,
|
||||||
|
})
|
||||||
|
await config.publish()
|
||||||
|
|
||||||
|
const response = await config.api.viewV2.search(viewId, undefined, {
|
||||||
|
usePublicUser: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(response.body.rows).toHaveLength(10)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("respects inherited permissions, not allowing not public views from public tables", async () => {
|
||||||
|
await config.api.permission.set({
|
||||||
|
roleId: roles.BUILTIN_ROLE_IDS.PUBLIC,
|
||||||
|
level: PermissionLevel.READ,
|
||||||
|
resourceId: tableId,
|
||||||
|
})
|
||||||
|
await config.api.permission.set({
|
||||||
|
roleId: roles.BUILTIN_ROLE_IDS.POWER,
|
||||||
|
level: PermissionLevel.READ,
|
||||||
|
resourceId: viewId,
|
||||||
|
})
|
||||||
|
await config.publish()
|
||||||
|
|
||||||
|
await config.api.viewV2.search(viewId, undefined, {
|
||||||
|
usePublicUser: true,
|
||||||
|
expectStatus: 403,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -6,11 +6,11 @@ import { isDevAppID } from "../db/utils"
|
||||||
// need this to call directly, so we can get a response
|
// need this to call directly, so we can get a response
|
||||||
import { automationQueue } from "./bullboard"
|
import { automationQueue } from "./bullboard"
|
||||||
import { checkTestFlag } from "../utilities/redis"
|
import { checkTestFlag } from "../utilities/redis"
|
||||||
|
import * as utils from "./utils"
|
||||||
import env from "../environment"
|
import env from "../environment"
|
||||||
import { context, db as dbCore } from "@budibase/backend-core"
|
import { context, db as dbCore } from "@budibase/backend-core"
|
||||||
import { Automation, Row, AutomationData, AutomationJob } from "@budibase/types"
|
import { Automation, Row, AutomationData, AutomationJob } from "@budibase/types"
|
||||||
import { executeSynchronously } from "../threads/automation"
|
import { executeSynchronously } from "../threads/automation"
|
||||||
import sdk from "../sdk"
|
|
||||||
|
|
||||||
export const TRIGGER_DEFINITIONS = definitions
|
export const TRIGGER_DEFINITIONS = definitions
|
||||||
const JOB_OPTS = {
|
const JOB_OPTS = {
|
||||||
|
@ -142,7 +142,7 @@ export async function rebootTrigger() {
|
||||||
let automations = await getAllAutomations()
|
let automations = await getAllAutomations()
|
||||||
let rebootEvents = []
|
let rebootEvents = []
|
||||||
for (let automation of automations) {
|
for (let automation of automations) {
|
||||||
if (sdk.automations.isReboot(automation)) {
|
if (utils.isRebootTrigger(automation)) {
|
||||||
const job = {
|
const job = {
|
||||||
automation,
|
automation,
|
||||||
event: {
|
event: {
|
||||||
|
|
|
@ -17,17 +17,16 @@ import {
|
||||||
import sdk from "../sdk"
|
import sdk from "../sdk"
|
||||||
import { automationsEnabled } from "../features"
|
import { automationsEnabled } from "../features"
|
||||||
|
|
||||||
|
const REBOOT_CRON = "@reboot"
|
||||||
const WH_STEP_ID = definitions.WEBHOOK.stepId
|
const WH_STEP_ID = definitions.WEBHOOK.stepId
|
||||||
|
const CRON_STEP_ID = definitions.CRON.stepId
|
||||||
let Runner: Thread
|
let Runner: Thread
|
||||||
if (automationsEnabled()) {
|
if (automationsEnabled()) {
|
||||||
Runner = new Thread(ThreadType.AUTOMATION)
|
Runner = new Thread(ThreadType.AUTOMATION)
|
||||||
}
|
}
|
||||||
|
|
||||||
function loggingArgs(
|
function loggingArgs(job: AutomationJob) {
|
||||||
job: AutomationJob,
|
return [
|
||||||
timing?: { start: number; complete?: boolean }
|
|
||||||
) {
|
|
||||||
const logs: any[] = [
|
|
||||||
{
|
{
|
||||||
_logKey: "automation",
|
_logKey: "automation",
|
||||||
trigger: job.data.automation.definition.trigger.event,
|
trigger: job.data.automation.definition.trigger.event,
|
||||||
|
@ -37,53 +36,24 @@ function loggingArgs(
|
||||||
jobId: job.id,
|
jobId: job.id,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
if (timing?.start) {
|
|
||||||
logs.push({
|
|
||||||
_logKey: "startTime",
|
|
||||||
start: timing.start,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (timing?.start && timing?.complete) {
|
|
||||||
const end = new Date().getTime()
|
|
||||||
const duration = end - timing.start
|
|
||||||
logs.push({
|
|
||||||
_logKey: "endTime",
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
logs.push({
|
|
||||||
_logKey: "duration",
|
|
||||||
duration,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return logs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function processEvent(job: AutomationJob) {
|
export async function processEvent(job: AutomationJob) {
|
||||||
const appId = job.data.event.appId!
|
const appId = job.data.event.appId!
|
||||||
const automationId = job.data.automation._id!
|
const automationId = job.data.automation._id!
|
||||||
const start = new Date().getTime()
|
|
||||||
const task = async () => {
|
const task = async () => {
|
||||||
try {
|
try {
|
||||||
// need to actually await these so that an error can be captured properly
|
// need to actually await these so that an error can be captured properly
|
||||||
console.log("automation running", ...loggingArgs(job, { start }))
|
console.log("automation running", ...loggingArgs(job))
|
||||||
|
|
||||||
const runFn = () => Runner.run(job)
|
const runFn = () => Runner.run(job)
|
||||||
const result = await quotas.addAutomation(runFn, {
|
const result = await quotas.addAutomation(runFn, {
|
||||||
automationId,
|
automationId,
|
||||||
})
|
})
|
||||||
const end = new Date().getTime()
|
console.log("automation completed", ...loggingArgs(job))
|
||||||
const duration = end - start
|
|
||||||
console.log(
|
|
||||||
"automation completed",
|
|
||||||
...loggingArgs(job, { start, complete: true })
|
|
||||||
)
|
|
||||||
return result
|
return result
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(
|
console.error(`automation was unable to run`, err, ...loggingArgs(job))
|
||||||
`automation was unable to run`,
|
|
||||||
err,
|
|
||||||
...loggingArgs(job, { start, complete: true })
|
|
||||||
)
|
|
||||||
return { err }
|
return { err }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,6 +133,19 @@ export async function clearMetadata() {
|
||||||
await db.bulkDocs(automationMetadata)
|
await db.bulkDocs(automationMetadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isCronTrigger(auto: Automation) {
|
||||||
|
return (
|
||||||
|
auto &&
|
||||||
|
auto.definition.trigger &&
|
||||||
|
auto.definition.trigger.stepId === CRON_STEP_ID
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isRebootTrigger(auto: Automation) {
|
||||||
|
const trigger = auto ? auto.definition.trigger : null
|
||||||
|
return isCronTrigger(auto) && trigger?.inputs.cron === REBOOT_CRON
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function handles checking of any cron jobs that need to be enabled/updated.
|
* This function handles checking of any cron jobs that need to be enabled/updated.
|
||||||
* @param {string} appId The ID of the app in which we are checking for webhooks
|
* @param {string} appId The ID of the app in which we are checking for webhooks
|
||||||
|
@ -170,14 +153,14 @@ export async function clearMetadata() {
|
||||||
*/
|
*/
|
||||||
export async function enableCronTrigger(appId: any, automation: Automation) {
|
export async function enableCronTrigger(appId: any, automation: Automation) {
|
||||||
const trigger = automation ? automation.definition.trigger : null
|
const trigger = automation ? automation.definition.trigger : null
|
||||||
const validCron = sdk.automations.isCron(automation) && trigger?.inputs.cron
|
|
||||||
const needsCreated =
|
|
||||||
!sdk.automations.isReboot(automation) &&
|
|
||||||
!sdk.automations.disabled(automation)
|
|
||||||
let enabled = false
|
let enabled = false
|
||||||
|
|
||||||
// need to create cron job
|
// need to create cron job
|
||||||
if (validCron && needsCreated) {
|
if (
|
||||||
|
isCronTrigger(automation) &&
|
||||||
|
!isRebootTrigger(automation) &&
|
||||||
|
trigger?.inputs.cron
|
||||||
|
) {
|
||||||
// make a job id rather than letting Bull decide, makes it easier to handle on way out
|
// make a job id rather than letting Bull decide, makes it easier to handle on way out
|
||||||
const jobId = `${appId}_cron_${newid()}`
|
const jobId = `${appId}_cron_${newid()}`
|
||||||
const job: any = await automationQueue.add(
|
const job: any = await automationQueue.add(
|
||||||
|
|
|
@ -3,28 +3,8 @@ import { ServiceType } from "@budibase/types"
|
||||||
coreEnv._set("SERVICE_TYPE", ServiceType.APPS)
|
coreEnv._set("SERVICE_TYPE", ServiceType.APPS)
|
||||||
import { join } from "path"
|
import { join } from "path"
|
||||||
|
|
||||||
function isTest() {
|
|
||||||
return isCypress() || isJest()
|
|
||||||
}
|
|
||||||
|
|
||||||
function isJest() {
|
|
||||||
return (
|
|
||||||
process.env.NODE_ENV === "jest" ||
|
|
||||||
(process.env.JEST_WORKER_ID != null &&
|
|
||||||
process.env.JEST_WORKER_ID !== "null")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function isDev() {
|
|
||||||
return process.env.NODE_ENV !== "production"
|
|
||||||
}
|
|
||||||
|
|
||||||
function isCypress() {
|
|
||||||
return process.env.NODE_ENV === "cypress"
|
|
||||||
}
|
|
||||||
|
|
||||||
let LOADED = false
|
let LOADED = false
|
||||||
if (!LOADED && isDev() && !isTest()) {
|
if (!LOADED && coreEnv.isDev() && !coreEnv.isTest()) {
|
||||||
require("dotenv").config({
|
require("dotenv").config({
|
||||||
path: join(__dirname, "..", ".env"),
|
path: join(__dirname, "..", ".env"),
|
||||||
})
|
})
|
||||||
|
@ -93,12 +73,12 @@ const environment = {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
environment[key] = value
|
environment[key] = value
|
||||||
},
|
},
|
||||||
isTest,
|
isTest: coreEnv.isTest,
|
||||||
isJest,
|
isJest: coreEnv.isJest,
|
||||||
isCypress,
|
|
||||||
isDev,
|
isDev: coreEnv.isDev,
|
||||||
isProd: () => {
|
isProd: () => {
|
||||||
return !isDev()
|
return !coreEnv.isDev()
|
||||||
},
|
},
|
||||||
isInThread: () => {
|
isInThread: () => {
|
||||||
return process.env.FORKED_PROCESS
|
return process.env.FORKED_PROCESS
|
||||||
|
@ -108,7 +88,7 @@ const environment = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// threading can cause memory issues with node-ts in development
|
// threading can cause memory issues with node-ts in development
|
||||||
if (isDev() && environment.DISABLE_THREADING == null) {
|
if (coreEnv.isDev() && environment.DISABLE_THREADING == null) {
|
||||||
environment._set("DISABLE_THREADING", "1")
|
environment._set("DISABLE_THREADING", "1")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,10 @@ import {
|
||||||
users,
|
users,
|
||||||
} from "@budibase/backend-core"
|
} from "@budibase/backend-core"
|
||||||
import { PermissionLevel, PermissionType, Role, UserCtx } from "@budibase/types"
|
import { PermissionLevel, PermissionType, Role, UserCtx } from "@budibase/types"
|
||||||
import { features } from "@budibase/pro"
|
|
||||||
import builderMiddleware from "./builder"
|
import builderMiddleware from "./builder"
|
||||||
import { isWebhookEndpoint } from "./utils"
|
import { isWebhookEndpoint } from "./utils"
|
||||||
import { paramResource } from "./resourceId"
|
import { paramResource } from "./resourceId"
|
||||||
import { extractViewInfoFromID, isViewID } from "../db/utils"
|
import sdk from "../sdk"
|
||||||
|
|
||||||
function hasResource(ctx: any) {
|
function hasResource(ctx: any) {
|
||||||
return ctx.resourceId != null
|
return ctx.resourceId != null
|
||||||
|
@ -77,31 +76,6 @@ const checkAuthorizedResource = async (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const resourceIdTranformers: Partial<
|
|
||||||
Record<PermissionType, (ctx: UserCtx) => Promise<void>>
|
|
||||||
> = {
|
|
||||||
[PermissionType.VIEW]: async ctx => {
|
|
||||||
const { resourceId } = ctx
|
|
||||||
if (!resourceId) {
|
|
||||||
ctx.throw(400, `Cannot obtain the view id`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isViewID(resourceId)) {
|
|
||||||
ctx.throw(400, `"${resourceId}" is not a valid view id`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (await features.isViewPermissionEnabled()) {
|
|
||||||
ctx.subResourceId = ctx.resourceId
|
|
||||||
ctx.resourceId = extractViewInfoFromID(resourceId).tableId
|
|
||||||
} else {
|
|
||||||
ctx.resourceId = extractViewInfoFromID(resourceId).tableId
|
|
||||||
delete ctx.subResourceId
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const authorized =
|
const authorized =
|
||||||
(
|
(
|
||||||
permType: PermissionType,
|
permType: PermissionType,
|
||||||
|
@ -121,8 +95,8 @@ const authorized =
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the resource roles
|
// get the resource roles
|
||||||
let resourceRoles: any = []
|
let resourceRoles: string[] = []
|
||||||
let otherLevelRoles: any = []
|
let otherLevelRoles: string[] = []
|
||||||
const otherLevel =
|
const otherLevel =
|
||||||
permLevel === PermissionLevel.READ
|
permLevel === PermissionLevel.READ
|
||||||
? PermissionLevel.WRITE
|
? PermissionLevel.WRITE
|
||||||
|
@ -133,21 +107,28 @@ const authorized =
|
||||||
paramResource(resourcePath)(ctx, () => {})
|
paramResource(resourcePath)(ctx, () => {})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resourceIdTranformers[permType]) {
|
|
||||||
await resourceIdTranformers[permType]!(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasResource(ctx)) {
|
if (hasResource(ctx)) {
|
||||||
const { resourceId, subResourceId } = ctx
|
const { resourceId, subResourceId } = ctx
|
||||||
resourceRoles = await roles.getRequiredResourceRole(permLevel!, {
|
|
||||||
resourceId,
|
const permissions = await sdk.permissions.getResourcePerms(resourceId)
|
||||||
subResourceId,
|
const subPermissions =
|
||||||
})
|
!!subResourceId &&
|
||||||
|
(await sdk.permissions.getResourcePerms(subResourceId))
|
||||||
|
|
||||||
|
function getPermLevel(permLevel: string) {
|
||||||
|
let result: string[] = []
|
||||||
|
if (permissions[permLevel]) {
|
||||||
|
result.push(permissions[permLevel].role)
|
||||||
|
}
|
||||||
|
if (subPermissions && subPermissions[permLevel]) {
|
||||||
|
result.push(subPermissions[permLevel].role)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceRoles = getPermLevel(permLevel!)
|
||||||
if (opts && opts.schema) {
|
if (opts && opts.schema) {
|
||||||
otherLevelRoles = await roles.getRequiredResourceRole(otherLevel, {
|
otherLevelRoles = getPermLevel(otherLevel!)
|
||||||
resourceId,
|
|
||||||
subResourceId,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,20 @@
|
||||||
jest.mock("@budibase/backend-core", () => ({
|
jest.mock("../../sdk/app/permissions", () => ({
|
||||||
...jest.requireActual("@budibase/backend-core"),
|
...jest.requireActual("../../sdk/app/permissions"),
|
||||||
roles: {
|
getResourcePerms: jest.fn().mockResolvedValue([]),
|
||||||
...jest.requireActual("@budibase/backend-core").roles,
|
|
||||||
getRequiredResourceRole: jest.fn().mockResolvedValue([]),
|
|
||||||
},
|
|
||||||
}))
|
|
||||||
jest.mock("../../environment", () => ({
|
|
||||||
prod: false,
|
|
||||||
isTest: () => true,
|
|
||||||
// @ts-ignore
|
|
||||||
isProd: () => this.prod,
|
|
||||||
_set: function (_key: string, value: string) {
|
|
||||||
this.prod = value === "production"
|
|
||||||
},
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
import { PermissionType, PermissionLevel } from "@budibase/types"
|
import {
|
||||||
|
PermissionType,
|
||||||
|
PermissionLevel,
|
||||||
|
PermissionSource,
|
||||||
|
} from "@budibase/types"
|
||||||
|
|
||||||
import authorizedMiddleware from "../authorized"
|
import authorizedMiddleware from "../authorized"
|
||||||
import env from "../../environment"
|
import env from "../../environment"
|
||||||
import { generateTableID, generateViewID } from "../../db/utils"
|
import { generateTableID, generateViewID } from "../../db/utils"
|
||||||
import { roles } from "@budibase/backend-core"
|
import { generator, mocks } from "@budibase/backend-core/tests"
|
||||||
import { mocks } from "@budibase/backend-core/tests"
|
|
||||||
import { initProMocks } from "../../tests/utilities/mocks/pro"
|
import { initProMocks } from "../../tests/utilities/mocks/pro"
|
||||||
|
import { getResourcePerms } from "../../sdk/app/permissions"
|
||||||
|
|
||||||
const APP_ID = ""
|
const APP_ID = ""
|
||||||
|
|
||||||
|
@ -189,23 +181,26 @@ describe("Authorization middleware", () => {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("view type", () => {
|
describe("with resource", () => {
|
||||||
const tableId = generateTableID()
|
let resourceId: string
|
||||||
const viewId = generateViewID(tableId)
|
const mockedGetResourcePerms = getResourcePerms as jest.MockedFunction<
|
||||||
|
typeof getResourcePerms
|
||||||
const mockedGetRequiredResourceRole =
|
>
|
||||||
roles.getRequiredResourceRole as jest.MockedFunction<
|
|
||||||
typeof roles.getRequiredResourceRole
|
|
||||||
>
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
config.setMiddlewareRequiredPermission(
|
config.setMiddlewareRequiredPermission(
|
||||||
PermissionType.VIEW,
|
PermissionType.VIEW,
|
||||||
PermissionLevel.READ
|
PermissionLevel.READ
|
||||||
)
|
)
|
||||||
config.setResourceId(viewId)
|
resourceId = generator.guid()
|
||||||
|
config.setResourceId(resourceId)
|
||||||
|
|
||||||
mockedGetRequiredResourceRole.mockResolvedValue(["PUBLIC"])
|
mockedGetResourcePerms.mockResolvedValue({
|
||||||
|
[PermissionLevel.READ]: {
|
||||||
|
role: "PUBLIC",
|
||||||
|
type: PermissionSource.BASE,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
config.setUser({
|
config.setUser({
|
||||||
_id: "user",
|
_id: "user",
|
||||||
|
@ -215,57 +210,14 @@ describe("Authorization middleware", () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("will ignore view permissions if flag is off", async () => {
|
it("will fetch resource permissions when resource is set", async () => {
|
||||||
await config.executeMiddleware()
|
await config.executeMiddleware()
|
||||||
|
|
||||||
expect(config.throw).not.toBeCalled()
|
expect(config.throw).not.toBeCalled()
|
||||||
expect(config.next).toHaveBeenCalled()
|
expect(config.next).toHaveBeenCalled()
|
||||||
|
|
||||||
expect(mockedGetRequiredResourceRole).toBeCalledTimes(1)
|
expect(mockedGetResourcePerms).toBeCalledTimes(1)
|
||||||
expect(mockedGetRequiredResourceRole).toBeCalledWith(
|
expect(mockedGetResourcePerms).toBeCalledWith(resourceId)
|
||||||
PermissionLevel.READ,
|
|
||||||
expect.objectContaining({
|
|
||||||
resourceId: tableId,
|
|
||||||
subResourceId: undefined,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("will use view permissions if flag is on", async () => {
|
|
||||||
mocks.licenses.useViewPermissions()
|
|
||||||
await config.executeMiddleware()
|
|
||||||
|
|
||||||
expect(config.throw).not.toBeCalled()
|
|
||||||
expect(config.next).toHaveBeenCalled()
|
|
||||||
|
|
||||||
expect(mockedGetRequiredResourceRole).toBeCalledTimes(1)
|
|
||||||
expect(mockedGetRequiredResourceRole).toBeCalledWith(
|
|
||||||
PermissionLevel.READ,
|
|
||||||
expect.objectContaining({
|
|
||||||
resourceId: tableId,
|
|
||||||
subResourceId: viewId,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("throw an exception if the resource id is not provided", async () => {
|
|
||||||
config.setResourceId(undefined)
|
|
||||||
await config.executeMiddleware()
|
|
||||||
expect(config.throw).toHaveBeenNthCalledWith(
|
|
||||||
1,
|
|
||||||
400,
|
|
||||||
"Cannot obtain the view id"
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it("throw an exception if the resource id is not a valid view id", async () => {
|
|
||||||
config.setResourceId(tableId)
|
|
||||||
await config.executeMiddleware()
|
|
||||||
expect(config.throw).toHaveBeenNthCalledWith(
|
|
||||||
1,
|
|
||||||
400,
|
|
||||||
`"${tableId}" is not a valid view id`
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
import { context } from "@budibase/backend-core"
|
|
||||||
import { Automation, AutomationState, DocumentType } from "@budibase/types"
|
|
||||||
import { definitions } from "../../../automations/triggerInfo"
|
|
||||||
|
|
||||||
const REBOOT_CRON = "@reboot"
|
|
||||||
|
|
||||||
export async function exists(automationId: string) {
|
|
||||||
if (!automationId?.startsWith(DocumentType.AUTOMATION)) {
|
|
||||||
throw new Error("Invalid automation ID.")
|
|
||||||
}
|
|
||||||
const db = context.getAppDB()
|
|
||||||
return db.docExists(automationId)
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function get(automationId: string) {
|
|
||||||
const db = context.getAppDB()
|
|
||||||
return (await db.get(automationId)) as Automation
|
|
||||||
}
|
|
||||||
|
|
||||||
export function disabled(automation: Automation) {
|
|
||||||
return automation.state === AutomationState.DISABLED || !hasSteps(automation)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isCron(automation: Automation) {
|
|
||||||
return (
|
|
||||||
automation?.definition.trigger &&
|
|
||||||
automation?.definition.trigger.stepId === definitions.CRON.stepId
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isReboot(automation: Automation) {
|
|
||||||
const trigger = automation?.definition.trigger
|
|
||||||
return isCron(automation) && trigger?.inputs.cron === REBOOT_CRON
|
|
||||||
}
|
|
||||||
|
|
||||||
export function hasSteps(automation: Automation) {
|
|
||||||
return automation?.definition?.steps?.length > 0
|
|
||||||
}
|
|
|
@ -1,9 +1,7 @@
|
||||||
import * as webhook from "./webhook"
|
import * as webhook from "./webhook"
|
||||||
import * as utils from "./utils"
|
import * as utils from "./utils"
|
||||||
import * as automations from "./automations"
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
webhook,
|
webhook,
|
||||||
utils,
|
utils,
|
||||||
...automations,
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ function tarFilesToTmp(tmpDir: string, files: string[]) {
|
||||||
export async function exportDB(
|
export async function exportDB(
|
||||||
dbName: string,
|
dbName: string,
|
||||||
opts: DBDumpOpts = {}
|
opts: DBDumpOpts = {}
|
||||||
): Promise<DBDumpOpts> {
|
): Promise<string> {
|
||||||
const exportOpts = {
|
const exportOpts = {
|
||||||
filter: opts?.filter,
|
filter: opts?.filter,
|
||||||
batch_size: 1000,
|
batch_size: 1000,
|
||||||
|
|
|
@ -1,18 +1,13 @@
|
||||||
import { context, db, env, roles } from "@budibase/backend-core"
|
import { db, env, roles } from "@budibase/backend-core"
|
||||||
import { features } from "@budibase/pro"
|
import { features } from "@budibase/pro"
|
||||||
import {
|
import {
|
||||||
DocumentType,
|
DocumentType,
|
||||||
PermissionLevel,
|
PermissionLevel,
|
||||||
PermissionSource,
|
PermissionSource,
|
||||||
PlanType,
|
PlanType,
|
||||||
Role,
|
|
||||||
VirtualDocumentType,
|
VirtualDocumentType,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import {
|
import { extractViewInfoFromID, isViewID } from "../../../db/utils"
|
||||||
extractViewInfoFromID,
|
|
||||||
getRoleParams,
|
|
||||||
isViewID,
|
|
||||||
} from "../../../db/utils"
|
|
||||||
import {
|
import {
|
||||||
CURRENTLY_SUPPORTED_LEVELS,
|
CURRENTLY_SUPPORTED_LEVELS,
|
||||||
getBasePermissions,
|
getBasePermissions,
|
||||||
|
@ -84,13 +79,8 @@ export async function allowsExplicitPermissions(resourceId: string) {
|
||||||
export async function getResourcePerms(
|
export async function getResourcePerms(
|
||||||
resourceId: string
|
resourceId: string
|
||||||
): Promise<ResourcePermissions> {
|
): Promise<ResourcePermissions> {
|
||||||
const db = context.getAppDB()
|
const rolesList = await roles.getAllRoles()
|
||||||
const body = await db.allDocs(
|
|
||||||
getRoleParams(null, {
|
|
||||||
include_docs: true,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
const rolesList = body.rows.map<Role>(row => row.doc)
|
|
||||||
let permissions: ResourcePermissions = {}
|
let permissions: ResourcePermissions = {}
|
||||||
|
|
||||||
const permsToInherit = await getInheritablePermissions(resourceId)
|
const permsToInherit = await getInheritablePermissions(resourceId)
|
||||||
|
|
|
@ -34,11 +34,6 @@ import pick from "lodash/pick"
|
||||||
export async function search(options: SearchParams) {
|
export async function search(options: SearchParams) {
|
||||||
const { tableId } = options
|
const { tableId } = options
|
||||||
|
|
||||||
// Fetch the whole table when running in cypress, as search doesn't work
|
|
||||||
if (!env.COUCH_DB_URL && env.isCypress()) {
|
|
||||||
return { rows: await fetch(tableId) }
|
|
||||||
}
|
|
||||||
|
|
||||||
const { paginate, query } = options
|
const { paginate, query } = options
|
||||||
|
|
||||||
const params: InternalSearchParams<any> = {
|
const params: InternalSearchParams<any> = {
|
||||||
|
|
|
@ -10,7 +10,6 @@ mocks.licenses.useUnlimited()
|
||||||
import { init as dbInit } from "../../db"
|
import { init as dbInit } from "../../db"
|
||||||
dbInit()
|
dbInit()
|
||||||
import env from "../../environment"
|
import env from "../../environment"
|
||||||
import { env as coreEnv } from "@budibase/backend-core"
|
|
||||||
import {
|
import {
|
||||||
basicTable,
|
basicTable,
|
||||||
basicRow,
|
basicRow,
|
||||||
|
@ -33,6 +32,7 @@ import {
|
||||||
encryption,
|
encryption,
|
||||||
auth,
|
auth,
|
||||||
roles,
|
roles,
|
||||||
|
env as coreEnv,
|
||||||
} from "@budibase/backend-core"
|
} from "@budibase/backend-core"
|
||||||
import * as controllers from "./controllers"
|
import * as controllers from "./controllers"
|
||||||
import { cleanup } from "../../utilities/fileSystem"
|
import { cleanup } from "../../utilities/fileSystem"
|
||||||
|
@ -51,7 +51,6 @@ import {
|
||||||
UserRoles,
|
UserRoles,
|
||||||
Automation,
|
Automation,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { BUILTIN_ROLE_IDS } from "@budibase/backend-core/src/security/roles"
|
|
||||||
|
|
||||||
import API from "./api"
|
import API from "./api"
|
||||||
|
|
||||||
|
@ -317,7 +316,7 @@ class TestConfiguration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async createGroup(roleId: string = BUILTIN_ROLE_IDS.BASIC) {
|
async createGroup(roleId: string = roles.BUILTIN_ROLE_IDS.BASIC) {
|
||||||
return context.doInTenant(this.tenantId!, async () => {
|
return context.doInTenant(this.tenantId!, async () => {
|
||||||
const baseGroup = structures.userGroups.userGroup()
|
const baseGroup = structures.userGroups.userGroup()
|
||||||
baseGroup.roles = {
|
baseGroup.roles = {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { default as threadUtils } from "./utils"
|
import { default as threadUtils } from "./utils"
|
||||||
import { Job } from "bull"
|
import { Job } from "bull"
|
||||||
threadUtils.threadSetup()
|
|
||||||
import {
|
import {
|
||||||
disableCronById,
|
disableCronById,
|
||||||
isErrorInOutput,
|
isErrorInOutput,
|
||||||
|
@ -35,8 +34,8 @@ import { cloneDeep } from "lodash/fp"
|
||||||
import { performance } from "perf_hooks"
|
import { performance } from "perf_hooks"
|
||||||
import * as sdkUtils from "../sdk/utils"
|
import * as sdkUtils from "../sdk/utils"
|
||||||
import env from "../environment"
|
import env from "../environment"
|
||||||
import sdk from "../sdk"
|
|
||||||
|
|
||||||
|
threadUtils.threadSetup()
|
||||||
const FILTER_STEP_ID = actions.BUILTIN_ACTION_DEFINITIONS.FILTER.stepId
|
const FILTER_STEP_ID = actions.BUILTIN_ACTION_DEFINITIONS.FILTER.stepId
|
||||||
const LOOP_STEP_ID = actions.BUILTIN_ACTION_DEFINITIONS.LOOP.stepId
|
const LOOP_STEP_ID = actions.BUILTIN_ACTION_DEFINITIONS.LOOP.stepId
|
||||||
const CRON_STEP_ID = triggerDefs.CRON.stepId
|
const CRON_STEP_ID = triggerDefs.CRON.stepId
|
||||||
|
@ -103,7 +102,7 @@ class Orchestrator {
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanupTriggerOutputs(stepId: string, triggerOutput: TriggerOutput) {
|
cleanupTriggerOutputs(stepId: string, triggerOutput: TriggerOutput) {
|
||||||
if (stepId === CRON_STEP_ID) {
|
if (stepId === CRON_STEP_ID && !triggerOutput.timestamp) {
|
||||||
triggerOutput.timestamp = Date.now()
|
triggerOutput.timestamp = Date.now()
|
||||||
}
|
}
|
||||||
return triggerOutput
|
return triggerOutput
|
||||||
|
@ -520,8 +519,7 @@ class Orchestrator {
|
||||||
|
|
||||||
export function execute(job: Job<AutomationData>, callback: WorkerCallback) {
|
export function execute(job: Job<AutomationData>, callback: WorkerCallback) {
|
||||||
const appId = job.data.event.appId
|
const appId = job.data.event.appId
|
||||||
const automation = job.data.automation
|
const automationId = job.data.automation._id
|
||||||
const automationId = automation._id
|
|
||||||
if (!appId) {
|
if (!appId) {
|
||||||
throw new Error("Unable to execute, event doesn't contain app ID.")
|
throw new Error("Unable to execute, event doesn't contain app ID.")
|
||||||
}
|
}
|
||||||
|
@ -532,30 +530,10 @@ export function execute(job: Job<AutomationData>, callback: WorkerCallback) {
|
||||||
appId,
|
appId,
|
||||||
automationId,
|
automationId,
|
||||||
task: async () => {
|
task: async () => {
|
||||||
let automation = job.data.automation,
|
|
||||||
isCron = sdk.automations.isCron(job.data.automation),
|
|
||||||
notFound = false
|
|
||||||
try {
|
|
||||||
automation = await sdk.automations.get(automationId)
|
|
||||||
} catch (err: any) {
|
|
||||||
// automation no longer exists
|
|
||||||
notFound = err
|
|
||||||
}
|
|
||||||
const disabled = sdk.automations.disabled(automation)
|
|
||||||
const stopAutomation = disabled || notFound
|
|
||||||
const envVars = await sdkUtils.getEnvironmentVariables()
|
const envVars = await sdkUtils.getEnvironmentVariables()
|
||||||
// put into automation thread for whole context
|
// put into automation thread for whole context
|
||||||
await context.doInEnvironmentContext(envVars, async () => {
|
await context.doInEnvironmentContext(envVars, async () => {
|
||||||
const automationOrchestrator = new Orchestrator(job)
|
const automationOrchestrator = new Orchestrator(job)
|
||||||
// hard stop on automations
|
|
||||||
if (isCron && stopAutomation) {
|
|
||||||
await automationOrchestrator.stopCron(
|
|
||||||
disabled ? "disabled" : "not_found"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (stopAutomation) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
const response = await automationOrchestrator.execute()
|
const response = await automationOrchestrator.execute()
|
||||||
callback(null, response)
|
callback(null, response)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
"prebuild": "rimraf dist/",
|
"prebuild": "rimraf dist/",
|
||||||
"build": "node ../../scripts/build.js && tsc -p tsconfig.build.json --emitDeclarationOnly --paths null",
|
"build": "node ../../scripts/build.js && tsc -p tsconfig.build.json --emitDeclarationOnly --paths null",
|
||||||
"build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput",
|
"build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput",
|
||||||
"dev:builder": "yarn prebuild && tsc -p tsconfig.json --watch --preserveWatchOutput",
|
"dev:builder": "tsc -p tsconfig.json --watch --preserveWatchOutput",
|
||||||
"check:types": "tsc -p tsconfig.json --noEmit --paths null"
|
"check:types": "tsc -p tsconfig.json --noEmit --paths null"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
"prebuild": "rimraf dist/",
|
"prebuild": "rimraf dist/",
|
||||||
"build": "node ../../scripts/build.js && tsc -p tsconfig.build.json --emitDeclarationOnly",
|
"build": "node ../../scripts/build.js && tsc -p tsconfig.build.json --emitDeclarationOnly",
|
||||||
"build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput",
|
"build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput",
|
||||||
"dev:builder": "yarn prebuild && tsc -p tsconfig.json --watch --preserveWatchOutput",
|
"dev:builder": "tsc -p tsconfig.json --watch --preserveWatchOutput",
|
||||||
"check:types": "tsc -p tsconfig.json --noEmit --paths null"
|
"check:types": "tsc -p tsconfig.json --noEmit --paths null"
|
||||||
},
|
},
|
||||||
"jest": {},
|
"jest": {},
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
"@budibase/nano": "10.1.2",
|
"@budibase/nano": "10.1.2",
|
||||||
"@types/json5": "2.2.0",
|
"@types/json5": "2.2.0",
|
||||||
"@types/koa": "2.13.4",
|
"@types/koa": "2.13.4",
|
||||||
"@types/node": "14.18.20",
|
"@types/node": "18.17.0",
|
||||||
"@types/pouchdb": "6.4.0",
|
"@types/pouchdb": "6.4.0",
|
||||||
"@types/redlock": "4.0.3",
|
"@types/redlock": "4.0.3",
|
||||||
"concurrently": "^7.6.0",
|
"concurrently": "^7.6.0",
|
||||||
|
|
|
@ -100,10 +100,6 @@ export const AutomationStepIdArray = [
|
||||||
...Object.values(AutomationTriggerStepId),
|
...Object.values(AutomationTriggerStepId),
|
||||||
]
|
]
|
||||||
|
|
||||||
export enum AutomationState {
|
|
||||||
DISABLED = "disabled",
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Automation extends Document {
|
export interface Automation extends Document {
|
||||||
definition: {
|
definition: {
|
||||||
steps: AutomationStep[]
|
steps: AutomationStep[]
|
||||||
|
@ -116,7 +112,6 @@ export interface Automation extends Document {
|
||||||
name: string
|
name: string
|
||||||
internal?: boolean
|
internal?: boolean
|
||||||
type?: string
|
type?: string
|
||||||
state?: AutomationState
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface BaseIOStructure {
|
interface BaseIOStructure {
|
||||||
|
|
|
@ -40,11 +40,6 @@ export type DatabasePutOpts = {
|
||||||
force?: boolean
|
force?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DocExistsResponse = {
|
|
||||||
_rev?: string
|
|
||||||
exists: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export type DatabaseCreateIndexOpts = {
|
export type DatabaseCreateIndexOpts = {
|
||||||
index: {
|
index: {
|
||||||
fields: string[]
|
fields: string[]
|
||||||
|
@ -95,7 +90,6 @@ export interface Database {
|
||||||
exists(): Promise<boolean>
|
exists(): Promise<boolean>
|
||||||
checkSetup(): Promise<Nano.DocumentScope<any>>
|
checkSetup(): Promise<Nano.DocumentScope<any>>
|
||||||
get<T>(id?: string): Promise<T>
|
get<T>(id?: string): Promise<T>
|
||||||
docExists(id: string): Promise<DocExistsResponse>
|
|
||||||
remove(
|
remove(
|
||||||
id: string | Document,
|
id: string | Document,
|
||||||
rev?: string
|
rev?: string
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
"predocker": "yarn build && cp ../../yarn.lock ./dist/",
|
"predocker": "yarn build && cp ../../yarn.lock ./dist/",
|
||||||
"build:docker": "yarn predocker && docker build . -t worker-service --label version=$BUDIBASE_RELEASE_VERSION",
|
"build:docker": "yarn predocker && docker build . -t worker-service --label version=$BUDIBASE_RELEASE_VERSION",
|
||||||
"dev:stack:init": "node ./scripts/dev/manage.js init",
|
"dev:stack:init": "node ./scripts/dev/manage.js init",
|
||||||
"dev:builder": "npm run dev:stack:init && rimraf dist/ && nodemon",
|
"dev:builder": "npm run dev:stack:init && nodemon",
|
||||||
"dev:built": "yarn run dev:stack:init && yarn run run:docker",
|
"dev:built": "yarn run dev:stack:init && yarn run run:docker",
|
||||||
"test": "bash scripts/test.sh",
|
"test": "bash scripts/test.sh",
|
||||||
"test:watch": "jest --watch",
|
"test:watch": "jest --watch",
|
||||||
|
@ -82,8 +82,8 @@
|
||||||
"@types/koa": "2.13.4",
|
"@types/koa": "2.13.4",
|
||||||
"@types/koa__router": "8.0.8",
|
"@types/koa__router": "8.0.8",
|
||||||
"@types/lodash": "^4.14.191",
|
"@types/lodash": "^4.14.191",
|
||||||
"@types/node": "14.18.20",
|
"@types/node": "18.17.0",
|
||||||
"@types/node-fetch": "2.6.1",
|
"@types/node-fetch": "2.6.4",
|
||||||
"@types/pouchdb": "6.4.0",
|
"@types/pouchdb": "6.4.0",
|
||||||
"@types/server-destroy": "1.0.1",
|
"@types/server-destroy": "1.0.1",
|
||||||
"@types/supertest": "2.0.12",
|
"@types/supertest": "2.0.12",
|
||||||
|
|
|
@ -266,17 +266,14 @@ export const onboardUsers = async (ctx: Ctx<InviteUsersRequest>) => {
|
||||||
|
|
||||||
// Temp password to be passed to the user.
|
// Temp password to be passed to the user.
|
||||||
createdPasswords[invite.email] = password
|
createdPasswords[invite.email] = password
|
||||||
let builder: { global: boolean; apps?: string[] } = { global: false }
|
|
||||||
if (invite.userInfo.appBuilders) {
|
|
||||||
builder.apps = invite.userInfo.appBuilders
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
email: invite.email,
|
email: invite.email,
|
||||||
password,
|
password,
|
||||||
forceResetPassword: true,
|
forceResetPassword: true,
|
||||||
roles: invite.userInfo.apps,
|
roles: invite.userInfo.apps,
|
||||||
admin: { global: false },
|
admin: invite.userInfo.admin,
|
||||||
builder,
|
builder: invite.userInfo.builder,
|
||||||
tenantId: tenancy.getTenantId(),
|
tenantId: tenancy.getTenantId(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -371,13 +368,10 @@ export const updateInvite = async (ctx: any) => {
|
||||||
...invite,
|
...invite,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!updateBody?.appBuilders || !updateBody.appBuilders?.length) {
|
if (!updateBody?.builder?.apps && updated.info?.builder?.apps) {
|
||||||
updated.info.appBuilders = []
|
updated.info.builder.apps = []
|
||||||
} else {
|
} else if (updateBody?.builder) {
|
||||||
updated.info.appBuilders = [
|
updated.info.builder = updateBody.builder
|
||||||
...(invite.info.appBuilders ?? []),
|
|
||||||
...updateBody.appBuilders,
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!updateBody?.apps || !Object.keys(updateBody?.apps).length) {
|
if (!updateBody?.apps || !Object.keys(updateBody?.apps).length) {
|
||||||
|
@ -409,15 +403,17 @@ export const inviteAccept = async (
|
||||||
lastName,
|
lastName,
|
||||||
password,
|
password,
|
||||||
email,
|
email,
|
||||||
|
admin: { global: info?.admin?.global || false },
|
||||||
roles: info.apps,
|
roles: info.apps,
|
||||||
tenantId: info.tenantId,
|
tenantId: info.tenantId,
|
||||||
}
|
}
|
||||||
let builder: { global: boolean; apps?: string[] } = { global: false }
|
let builder: { global: boolean; apps?: string[] } = {
|
||||||
|
global: info?.builder?.global || false,
|
||||||
|
}
|
||||||
|
|
||||||
if (info.appBuilders) {
|
if (info?.builder?.apps) {
|
||||||
builder.apps = info.appBuilders
|
builder.apps = info.builder.apps
|
||||||
request.builder = builder
|
request.builder = builder
|
||||||
delete info.appBuilders
|
|
||||||
}
|
}
|
||||||
delete info.apps
|
delete info.apps
|
||||||
request = {
|
request = {
|
||||||
|
|
|
@ -10,7 +10,6 @@ export const fetch = async (ctx: Ctx) => {
|
||||||
accountPortalUrl: env.ACCOUNT_PORTAL_URL,
|
accountPortalUrl: env.ACCOUNT_PORTAL_URL,
|
||||||
disableAccountPortal: env.DISABLE_ACCOUNT_PORTAL,
|
disableAccountPortal: env.DISABLE_ACCOUNT_PORTAL,
|
||||||
baseUrl: env.PLATFORM_URL,
|
baseUrl: env.PLATFORM_URL,
|
||||||
// in test need to pretend its in production for the UI (Cypress)
|
|
||||||
isDev: env.isDev() && !env.isTest(),
|
isDev: env.isDev() && !env.isTest(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,20 +4,8 @@ import { join } from "path"
|
||||||
|
|
||||||
coreEnv._set("SERVICE_TYPE", ServiceType.WORKER)
|
coreEnv._set("SERVICE_TYPE", ServiceType.WORKER)
|
||||||
|
|
||||||
function isDev() {
|
|
||||||
return process.env.NODE_ENV !== "production"
|
|
||||||
}
|
|
||||||
|
|
||||||
function isTest() {
|
|
||||||
return (
|
|
||||||
process.env.NODE_ENV === "jest" ||
|
|
||||||
process.env.NODE_ENV === "cypress" ||
|
|
||||||
process.env.JEST_WORKER_ID != null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
let LOADED = false
|
let LOADED = false
|
||||||
if (!LOADED && isDev() && !isTest()) {
|
if (!LOADED && coreEnv.isDev() && !coreEnv.isTest()) {
|
||||||
require("dotenv").config({
|
require("dotenv").config({
|
||||||
path: join(__dirname, "..", ".env"),
|
path: join(__dirname, "..", ".env"),
|
||||||
})
|
})
|
||||||
|
@ -85,16 +73,16 @@ const environment = {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
environment[key] = value
|
environment[key] = value
|
||||||
},
|
},
|
||||||
isDev,
|
isDev: coreEnv.isDev,
|
||||||
isTest,
|
isTest: coreEnv.isTest,
|
||||||
isProd: () => {
|
isProd: () => {
|
||||||
return !isDev()
|
return !coreEnv.isDev()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// if some var haven't been set, define them
|
// if some var haven't been set, define them
|
||||||
if (!environment.APPS_URL) {
|
if (!environment.APPS_URL) {
|
||||||
environment.APPS_URL = isDev()
|
environment.APPS_URL = coreEnv.isDev()
|
||||||
? "http://localhost:4001"
|
? "http://localhost:4001"
|
||||||
: "http://app-service:4002"
|
: "http://app-service:4002"
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
"@budibase/types": "^2.3.17",
|
"@budibase/types": "^2.3.17",
|
||||||
"@trendyol/jest-testcontainers": "2.1.1",
|
"@trendyol/jest-testcontainers": "2.1.1",
|
||||||
"@types/jest": "29.5.3",
|
"@types/jest": "29.5.3",
|
||||||
"@types/node-fetch": "2.6.2",
|
"@types/node-fetch": "2.6.4",
|
||||||
"chance": "1.1.8",
|
"chance": "1.1.8",
|
||||||
"dotenv": "16.0.1",
|
"dotenv": "16.0.1",
|
||||||
"jest": "29.6.2",
|
"jest": "29.6.2",
|
||||||
|
@ -43,6 +43,6 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/backend-core": "^2.3.17",
|
"@budibase/backend-core": "^2.3.17",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"node-fetch": "2"
|
"node-fetch": "2.6.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,4 +114,10 @@ export default class AccountAPI extends BaseAPI {
|
||||||
})
|
})
|
||||||
}, opts)
|
}, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async self(opts: APIRequestOpts = { status: 200 }) {
|
||||||
|
return this.doRequest(() => {
|
||||||
|
return this.client.get(`/api/auth/self`)
|
||||||
|
}, opts)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { Response } from "node-fetch"
|
||||||
import AccountInternalAPIClient from "../AccountInternalAPIClient"
|
import AccountInternalAPIClient from "../AccountInternalAPIClient"
|
||||||
import { APIRequestOpts } from "../../../types"
|
import { APIRequestOpts } from "../../../types"
|
||||||
import BaseAPI from "./BaseAPI"
|
import BaseAPI from "./BaseAPI"
|
||||||
|
import { Header } from "@budibase/backend-core"
|
||||||
|
|
||||||
export default class AuthAPI extends BaseAPI {
|
export default class AuthAPI extends BaseAPI {
|
||||||
client: AccountInternalAPIClient
|
client: AccountInternalAPIClient
|
||||||
|
@ -27,4 +28,41 @@ export default class AuthAPI extends BaseAPI {
|
||||||
return [res, cookie]
|
return [res, cookie]
|
||||||
}, opts)
|
}, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async logout(opts: APIRequestOpts = { status: 200 }) {
|
||||||
|
return this.doRequest(() => {
|
||||||
|
return this.client.post(`/api/auth/logout`)
|
||||||
|
}, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
async resetPassword(
|
||||||
|
email: string,
|
||||||
|
opts: APIRequestOpts = { status: 200 }
|
||||||
|
): Promise<[Response, string]> {
|
||||||
|
return this.doRequest(async () => {
|
||||||
|
const [response] = await this.client.post(`/api/auth/reset`, {
|
||||||
|
body: { email },
|
||||||
|
headers: {
|
||||||
|
[Header.RETURN_RESET_PASSWORD_CODE]: "1",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const code = response.headers.get(Header.RESET_PASSWORD_CODE)
|
||||||
|
return [response, code]
|
||||||
|
}, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
async resetPasswordUpdate(
|
||||||
|
resetCode: string,
|
||||||
|
password: string,
|
||||||
|
opts: APIRequestOpts = { status: 200 }
|
||||||
|
) {
|
||||||
|
return this.doRequest(() => {
|
||||||
|
return this.client.post(`/api/auth/reset/update`, {
|
||||||
|
body: {
|
||||||
|
resetCode: resetCode,
|
||||||
|
password: password,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}, opts)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import TestConfiguration from "../../config/TestConfiguration"
|
import TestConfiguration from "../../config/TestConfiguration"
|
||||||
import * as fixtures from "../../fixtures"
|
import * as fixtures from "../../fixtures"
|
||||||
import { generator } from "../../../shared"
|
import { generator } from "../../../shared"
|
||||||
|
import { Hosting } from "@budibase/types"
|
||||||
|
|
||||||
describe("Account Internal Operations", () => {
|
describe("Account Internal Operations", () => {
|
||||||
const config = new TestConfiguration()
|
const config = new TestConfiguration()
|
||||||
|
@ -20,7 +21,9 @@ describe("Account Internal Operations", () => {
|
||||||
|
|
||||||
// Create new account
|
// Create new account
|
||||||
const [_, account] = await config.api.accounts.create({
|
const [_, account] = await config.api.accounts.create({
|
||||||
...fixtures.accounts.generateAccount(),
|
...fixtures.accounts.generateAccount({
|
||||||
|
hosting: Hosting.CLOUD,
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
// New account can be deleted
|
// New account can be deleted
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import TestConfiguration from "../../config/TestConfiguration"
|
import TestConfiguration from "../../config/TestConfiguration"
|
||||||
import * as fixtures from "../../fixtures"
|
import * as fixtures from "../../fixtures"
|
||||||
import { generator } from "../../../shared"
|
import { generator } from "../../../shared"
|
||||||
|
import { Hosting } from "@budibase/types"
|
||||||
|
|
||||||
describe("Accounts", () => {
|
describe("Accounts", () => {
|
||||||
const config = new TestConfiguration()
|
const config = new TestConfiguration()
|
||||||
|
@ -16,7 +17,9 @@ describe("Accounts", () => {
|
||||||
it("performs signup and deletion flow", async () => {
|
it("performs signup and deletion flow", async () => {
|
||||||
await config.doInNewState(async () => {
|
await config.doInNewState(async () => {
|
||||||
// Create account
|
// Create account
|
||||||
const createAccountRequest = fixtures.accounts.generateAccount()
|
const createAccountRequest = fixtures.accounts.generateAccount({
|
||||||
|
hosting: Hosting.CLOUD,
|
||||||
|
})
|
||||||
const email = createAccountRequest.email
|
const email = createAccountRequest.email
|
||||||
const tenantId = createAccountRequest.tenantId
|
const tenantId = createAccountRequest.tenantId
|
||||||
|
|
||||||
|
@ -42,9 +45,16 @@ describe("Accounts", () => {
|
||||||
// Send the verification request
|
// Send the verification request
|
||||||
await config.accountsApi.accounts.verifyAccount(code!)
|
await config.accountsApi.accounts.verifyAccount(code!)
|
||||||
|
|
||||||
|
// Verify self response is unauthorized
|
||||||
|
await config.api.accounts.self({ status: 403 })
|
||||||
|
|
||||||
// Can now log in to the account
|
// Can now log in to the account
|
||||||
await config.loginAsAccount(createAccountRequest)
|
await config.loginAsAccount(createAccountRequest)
|
||||||
|
|
||||||
|
// Verify self response matches account
|
||||||
|
const [selfRes, selfBody] = await config.api.accounts.self()
|
||||||
|
expect(selfBody.email).toBe(email)
|
||||||
|
|
||||||
// Delete account
|
// Delete account
|
||||||
await config.api.accounts.deleteCurrentAccount()
|
await config.api.accounts.deleteCurrentAccount()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
import TestConfiguration from "../../config/TestConfiguration"
|
||||||
|
import * as fixtures from "../../fixtures"
|
||||||
|
import { generator } from "../../../shared"
|
||||||
|
import { Hosting } from "@budibase/types"
|
||||||
|
|
||||||
|
describe("Password Management", () => {
|
||||||
|
const config = new TestConfiguration()
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await config.beforeAll()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await config.afterAll()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("performs password reset flow", async () => {
|
||||||
|
// Create account
|
||||||
|
const createAccountRequest = fixtures.accounts.generateAccount({
|
||||||
|
hosting: Hosting.CLOUD,
|
||||||
|
})
|
||||||
|
await config.api.accounts.create(createAccountRequest, { autoVerify: true })
|
||||||
|
|
||||||
|
// Request password reset to get code
|
||||||
|
const [_, code] = await config.api.auth.resetPassword(
|
||||||
|
createAccountRequest.email
|
||||||
|
)
|
||||||
|
|
||||||
|
// Change password using code
|
||||||
|
const password = generator.string()
|
||||||
|
await config.api.auth.resetPasswordUpdate(code, password)
|
||||||
|
|
||||||
|
// Login using the new password
|
||||||
|
await config.api.auth.login(createAccountRequest.email, password)
|
||||||
|
|
||||||
|
// Logout of account
|
||||||
|
await config.api.auth.logout()
|
||||||
|
|
||||||
|
// Cannot log in using old password
|
||||||
|
await config.api.auth.login(
|
||||||
|
createAccountRequest.email,
|
||||||
|
createAccountRequest.password,
|
||||||
|
{ status: 403 }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
|
@ -15,7 +15,11 @@ const { nodeExternalsPlugin } = require("esbuild-node-externals")
|
||||||
|
|
||||||
var argv = require("minimist")(process.argv.slice(2))
|
var argv = require("minimist")(process.argv.slice(2))
|
||||||
|
|
||||||
function runBuild(entry, outfile) {
|
function runBuild(
|
||||||
|
entry,
|
||||||
|
outfile,
|
||||||
|
opts = { skipMeta: false, bundle: true, silent: false }
|
||||||
|
) {
|
||||||
const isDev = process.env.NODE_ENV !== "production"
|
const isDev = process.env.NODE_ENV !== "production"
|
||||||
const tsconfig = argv["p"] || `tsconfig.build.json`
|
const tsconfig = argv["p"] || `tsconfig.build.json`
|
||||||
const tsconfigPathPluginContent = JSON.parse(
|
const tsconfigPathPluginContent = JSON.parse(
|
||||||
|
@ -36,12 +40,16 @@ function runBuild(entry, outfile) {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const metafile = !opts.skipMeta
|
||||||
|
const { bundle } = opts
|
||||||
|
|
||||||
const sharedConfig = {
|
const sharedConfig = {
|
||||||
entryPoints: [entry],
|
entryPoints: [entry],
|
||||||
bundle: true,
|
bundle,
|
||||||
minify: !isDev,
|
minify: !isDev,
|
||||||
sourcemap: isDev,
|
sourcemap: isDev,
|
||||||
tsconfig,
|
tsconfig,
|
||||||
|
format: opts?.forcedFormat,
|
||||||
plugins: [
|
plugins: [
|
||||||
TsconfigPathsPlugin({ tsconfig: tsconfigPathPluginContent }),
|
TsconfigPathsPlugin({ tsconfig: tsconfigPathPluginContent }),
|
||||||
nodeExternalsPlugin(),
|
nodeExternalsPlugin(),
|
||||||
|
@ -50,15 +58,10 @@ function runBuild(entry, outfile) {
|
||||||
loader: {
|
loader: {
|
||||||
".svelte": "copy",
|
".svelte": "copy",
|
||||||
},
|
},
|
||||||
metafile: true,
|
metafile,
|
||||||
external: [
|
external: bundle
|
||||||
"deasync",
|
? ["deasync", "mock-aws-s3", "nock", "pino", "koa-pino-logger", "bull"]
|
||||||
"mock-aws-s3",
|
: undefined,
|
||||||
"nock",
|
|
||||||
"pino",
|
|
||||||
"koa-pino-logger",
|
|
||||||
"bull",
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
build({
|
build({
|
||||||
|
@ -71,16 +74,19 @@ function runBuild(entry, outfile) {
|
||||||
fs.copyFileSync(file, `${process.cwd()}/dist/${path.basename(file)}`)
|
fs.copyFileSync(file, `${process.cwd()}/dist/${path.basename(file)}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(
|
!opts.silent &&
|
||||||
"\x1b[32m%s\x1b[0m",
|
console.log(
|
||||||
`Build successfully in ${(Date.now() - start) / 1000} seconds`
|
"\x1b[32m%s\x1b[0m",
|
||||||
)
|
`Build successfully in ${(Date.now() - start) / 1000} seconds`
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
fs.writeFileSync(
|
if (metafile) {
|
||||||
`dist/${path.basename(outfile)}.meta.json`,
|
fs.writeFileSync(
|
||||||
JSON.stringify(result.metafile)
|
`dist/${path.basename(outfile)}.meta.json`,
|
||||||
)
|
JSON.stringify(result.metafile)
|
||||||
|
)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,89 +0,0 @@
|
||||||
echo "Linking backend-core"
|
|
||||||
cd packages/backend-core
|
|
||||||
yarn unlink
|
|
||||||
yarn link
|
|
||||||
cd -
|
|
||||||
|
|
||||||
echo "Linking string-templates"
|
|
||||||
cd packages/string-templates
|
|
||||||
yarn unlink
|
|
||||||
yarn link
|
|
||||||
cd -
|
|
||||||
|
|
||||||
echo "Linking types"
|
|
||||||
cd packages/types
|
|
||||||
yarn unlink
|
|
||||||
yarn link
|
|
||||||
cd -
|
|
||||||
|
|
||||||
echo "Linking bbui"
|
|
||||||
cd packages/bbui
|
|
||||||
yarn unlink
|
|
||||||
yarn link
|
|
||||||
cd -
|
|
||||||
|
|
||||||
echo "Linking frontend-core"
|
|
||||||
cd packages/frontend-core
|
|
||||||
yarn unlink
|
|
||||||
yarn link
|
|
||||||
cd -
|
|
||||||
|
|
||||||
echo "Linking shared-core"
|
|
||||||
cd packages/shared-core
|
|
||||||
yarn unlink
|
|
||||||
yarn link
|
|
||||||
cd -
|
|
||||||
|
|
||||||
if [ -d packages/pro/src ]; then
|
|
||||||
pro_loaded_locally=true
|
|
||||||
else
|
|
||||||
pro_loaded_locally=false
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $pro_loaded_locally = true ]; then
|
|
||||||
echo "Linking pro"
|
|
||||||
cd packages/pro
|
|
||||||
yarn unlink
|
|
||||||
yarn link
|
|
||||||
cd -
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -d "../account-portal" ]; then
|
|
||||||
cd ../account-portal
|
|
||||||
echo "Bootstrapping account-portal"
|
|
||||||
yarn bootstrap
|
|
||||||
|
|
||||||
cd packages/server
|
|
||||||
echo "Linking backend-core to account-portal (server)"
|
|
||||||
yarn link "@budibase/backend-core"
|
|
||||||
|
|
||||||
echo "Linking string-templates to account-portal (server)"
|
|
||||||
yarn link "@budibase/string-templates"
|
|
||||||
|
|
||||||
echo "Linking types to account-portal (server)"
|
|
||||||
yarn link "@budibase/types"
|
|
||||||
|
|
||||||
echo "Linking shared-core to account-portal (server)"
|
|
||||||
yarn link "@budibase/shared-core"
|
|
||||||
|
|
||||||
if [ $pro_loaded_locally = true ]; then
|
|
||||||
echo "Linking pro to account-portal (server)"
|
|
||||||
yarn link "@budibase/pro"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd ../ui
|
|
||||||
echo "Linking bbui to account-portal (ui)"
|
|
||||||
yarn link "@budibase/bbui"
|
|
||||||
|
|
||||||
echo "Linking shared-core to account-portal (ui)"
|
|
||||||
yarn link "@budibase/shared-core"
|
|
||||||
|
|
||||||
echo "Linking string-templates to account-portal (ui)"
|
|
||||||
yarn link "@budibase/string-templates"
|
|
||||||
|
|
||||||
echo "Linking types to account-portal (ui)"
|
|
||||||
yarn link "@budibase/types"
|
|
||||||
|
|
||||||
echo "Linking frontend-core to account-portal (ui)"
|
|
||||||
yarn link "@budibase/frontend-core"
|
|
||||||
fi
|
|
|
@ -1,16 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Define the packages
|
|
||||||
PACKAGES=("@budibase/backend-core" "@budibase/worker" "@budibase/server" "@budibase/string-templates" "@budibase/types" "@budibase/shared-core")
|
|
||||||
|
|
||||||
# Generate the scope arguments
|
|
||||||
SCOPE_ARGS=""
|
|
||||||
for PACKAGE in "${PACKAGES[@]}"; do
|
|
||||||
SCOPE_ARGS+="--scope $PACKAGE "
|
|
||||||
done
|
|
||||||
|
|
||||||
# Run the commands with the scope arguments
|
|
||||||
for COMMAND in "$@"; do
|
|
||||||
echo "Running: $COMMAND $SCOPE_ARGS"
|
|
||||||
yarn $COMMAND $SCOPE_ARGS
|
|
||||||
done
|
|
371
yarn.lock
371
yarn.lock
|
@ -2832,38 +2832,6 @@
|
||||||
string-width "^4.2.0"
|
string-width "^4.2.0"
|
||||||
y18n "^5.0.5"
|
y18n "^5.0.5"
|
||||||
|
|
||||||
"@cypress/request@^2.88.10":
|
|
||||||
version "2.88.11"
|
|
||||||
resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.11.tgz#5a4c7399bc2d7e7ed56e92ce5acb620c8b187047"
|
|
||||||
integrity sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w==
|
|
||||||
dependencies:
|
|
||||||
aws-sign2 "~0.7.0"
|
|
||||||
aws4 "^1.8.0"
|
|
||||||
caseless "~0.12.0"
|
|
||||||
combined-stream "~1.0.6"
|
|
||||||
extend "~3.0.2"
|
|
||||||
forever-agent "~0.6.1"
|
|
||||||
form-data "~2.3.2"
|
|
||||||
http-signature "~1.3.6"
|
|
||||||
is-typedarray "~1.0.0"
|
|
||||||
isstream "~0.1.2"
|
|
||||||
json-stringify-safe "~5.0.1"
|
|
||||||
mime-types "~2.1.19"
|
|
||||||
performance-now "^2.1.0"
|
|
||||||
qs "~6.10.3"
|
|
||||||
safe-buffer "^5.1.2"
|
|
||||||
tough-cookie "~2.5.0"
|
|
||||||
tunnel-agent "^0.6.0"
|
|
||||||
uuid "^8.3.2"
|
|
||||||
|
|
||||||
"@cypress/xvfb@^1.2.4":
|
|
||||||
version "1.2.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/@cypress/xvfb/-/xvfb-1.2.4.tgz#2daf42e8275b39f4aa53c14214e557bd14e7748a"
|
|
||||||
integrity sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==
|
|
||||||
dependencies:
|
|
||||||
debug "^3.1.0"
|
|
||||||
lodash.once "^4.1.1"
|
|
||||||
|
|
||||||
"@dabh/diagnostics@^2.0.2":
|
"@dabh/diagnostics@^2.0.2":
|
||||||
version "2.0.3"
|
version "2.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.3.tgz#7f7e97ee9a725dffc7808d93668cc984e1dc477a"
|
resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.3.tgz#7f7e97ee9a725dffc7808d93668cc984e1dc477a"
|
||||||
|
@ -6301,10 +6269,10 @@
|
||||||
"@types/tedious" "*"
|
"@types/tedious" "*"
|
||||||
tarn "^3.0.1"
|
tarn "^3.0.1"
|
||||||
|
|
||||||
"@types/node-fetch@2.6.1":
|
"@types/node-fetch@2.6.4":
|
||||||
version "2.6.1"
|
version "2.6.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.1.tgz#8f127c50481db65886800ef496f20bbf15518975"
|
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.4.tgz#1bc3a26de814f6bf466b25aeb1473fa1afe6a660"
|
||||||
integrity sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==
|
integrity sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
form-data "^3.0.0"
|
form-data "^3.0.0"
|
||||||
|
@ -6322,16 +6290,16 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f"
|
||||||
integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==
|
integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==
|
||||||
|
|
||||||
"@types/node@14.18.20":
|
|
||||||
version "14.18.20"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.20.tgz#268f028b36eaf51181c3300252f605488c4f0650"
|
|
||||||
integrity sha512-Q8KKwm9YqEmUBRsqJ2GWJDtXltBDxTdC4m5vTdXBolu2PeQh8LX+f6BTwU+OuXPu37fLxoN6gidqBmnky36FXA==
|
|
||||||
|
|
||||||
"@types/node@16.9.1":
|
"@types/node@16.9.1":
|
||||||
version "16.9.1"
|
version "16.9.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.9.1.tgz#0611b37db4246c937feef529ddcc018cf8e35708"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.9.1.tgz#0611b37db4246c937feef529ddcc018cf8e35708"
|
||||||
integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==
|
integrity sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==
|
||||||
|
|
||||||
|
"@types/node@18.17.0":
|
||||||
|
version "18.17.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.17.0.tgz#35d44267a33dd46b49ee0f73d31b05fd7407e290"
|
||||||
|
integrity sha512-GXZxEtOxYGFchyUzxvKI14iff9KZ2DI+A6a37o6EQevtg6uO9t+aUZKcaC1Te5Ng1OnLM7K9NVVj+FbecD9cJg==
|
||||||
|
|
||||||
"@types/node@>=10.0.0", "@types/node@>=12.12.47", "@types/node@>=13.13.4", "@types/node@>=13.7.0":
|
"@types/node@>=10.0.0", "@types/node@>=12.12.47", "@types/node@>=13.13.4", "@types/node@>=13.7.0":
|
||||||
version "18.14.5"
|
version "18.14.5"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.14.5.tgz#4a13a6445862159303fc38586598a9396fc408b3"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.14.5.tgz#4a13a6445862159303fc38586598a9396fc408b3"
|
||||||
|
@ -6342,7 +6310,7 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240"
|
||||||
integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==
|
integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==
|
||||||
|
|
||||||
"@types/node@>=8.0.0 <15", "@types/node@^14.14.31":
|
"@types/node@>=8.0.0 <15":
|
||||||
version "14.18.37"
|
version "14.18.37"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.37.tgz#0bfcd173e8e1e328337473a8317e37b3b14fd30d"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.37.tgz#0bfcd173e8e1e328337473a8317e37b3b14fd30d"
|
||||||
integrity sha512-7GgtHCs/QZrBrDzgIJnQtuSvhFSwhyYSI2uafSwZoNt1iOGhEN5fwNrQMjtONyHm9+/LoA4453jH0CMYcr06Pg==
|
integrity sha512-7GgtHCs/QZrBrDzgIJnQtuSvhFSwhyYSI2uafSwZoNt1iOGhEN5fwNrQMjtONyHm9+/LoA4453jH0CMYcr06Pg==
|
||||||
|
@ -6603,16 +6571,6 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/sinonjs__fake-timers@8.1.1":
|
|
||||||
version "8.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3"
|
|
||||||
integrity sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==
|
|
||||||
|
|
||||||
"@types/sizzle@^2.3.2":
|
|
||||||
version "2.3.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.3.tgz#ff5e2f1902969d305225a047c8a0fd5c915cebef"
|
|
||||||
integrity sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==
|
|
||||||
|
|
||||||
"@types/stack-utils@^2.0.0":
|
"@types/stack-utils@^2.0.0":
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
|
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
|
||||||
|
@ -6738,13 +6696,6 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/yargs-parser" "*"
|
"@types/yargs-parser" "*"
|
||||||
|
|
||||||
"@types/yauzl@^2.9.1":
|
|
||||||
version "2.10.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.0.tgz#b3248295276cf8c6f153ebe6a9aba0c988cb2599"
|
|
||||||
integrity sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==
|
|
||||||
dependencies:
|
|
||||||
"@types/node" "*"
|
|
||||||
|
|
||||||
"@typescript-eslint/parser@5.45.0":
|
"@typescript-eslint/parser@5.45.0":
|
||||||
version "5.45.0"
|
version "5.45.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.45.0.tgz#b18a5f6b3cf1c2b3e399e9d2df4be40d6b0ddd0e"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.45.0.tgz#b18a5f6b3cf1c2b3e399e9d2df4be40d6b0ddd0e"
|
||||||
|
@ -7301,7 +7252,7 @@ ansi-colors@^4.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
|
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
|
||||||
integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
|
integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
|
||||||
|
|
||||||
ansi-escapes@^4.2.1, ansi-escapes@^4.3.0:
|
ansi-escapes@^4.2.1:
|
||||||
version "4.3.2"
|
version "4.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
|
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
|
||||||
integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==
|
integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==
|
||||||
|
@ -7436,11 +7387,6 @@ arangojs@7.2.0:
|
||||||
x3-linkedlist "1.2.0"
|
x3-linkedlist "1.2.0"
|
||||||
xhr "^2.4.1"
|
xhr "^2.4.1"
|
||||||
|
|
||||||
arch@^2.2.0:
|
|
||||||
version "2.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11"
|
|
||||||
integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==
|
|
||||||
|
|
||||||
archive-type@^4.0.0:
|
archive-type@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/archive-type/-/archive-type-4.0.0.tgz#f92e72233056dfc6969472749c267bdb046b1d70"
|
resolved "https://registry.yarnpkg.com/archive-type/-/archive-type-4.0.0.tgz#f92e72233056dfc6969472749c267bdb046b1d70"
|
||||||
|
@ -7697,7 +7643,7 @@ async-value@^1.2.2:
|
||||||
resolved "https://registry.yarnpkg.com/async-value/-/async-value-1.2.2.tgz#84517a1e7cb6b1a5b5e181fa31be10437b7fb125"
|
resolved "https://registry.yarnpkg.com/async-value/-/async-value-1.2.2.tgz#84517a1e7cb6b1a5b5e181fa31be10437b7fb125"
|
||||||
integrity sha512-8rwtYe32OAS1W9CTwvknoyts+mc3ta8N7Pi0h7AjkMaKvsFbr39K+gEfZ7Z81aPXQ1sK5M23lgLy1QfZpcpadQ==
|
integrity sha512-8rwtYe32OAS1W9CTwvknoyts+mc3ta8N7Pi0h7AjkMaKvsFbr39K+gEfZ7Z81aPXQ1sK5M23lgLy1QfZpcpadQ==
|
||||||
|
|
||||||
async@^3.2.0, async@^3.2.1, async@^3.2.3:
|
async@^3.2.1, async@^3.2.3:
|
||||||
version "3.2.4"
|
version "3.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c"
|
resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c"
|
||||||
integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==
|
integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==
|
||||||
|
@ -8137,11 +8083,6 @@ bl@~0.8.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
readable-stream "~1.0.26"
|
readable-stream "~1.0.26"
|
||||||
|
|
||||||
blob-util@^2.0.2:
|
|
||||||
version "2.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/blob-util/-/blob-util-2.0.2.tgz#3b4e3c281111bb7f11128518006cdc60b403a1eb"
|
|
||||||
integrity sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==
|
|
||||||
|
|
||||||
bluebird@3.7.2, bluebird@^3.5.1, bluebird@^3.7.2:
|
bluebird@3.7.2, bluebird@^3.5.1, bluebird@^3.7.2:
|
||||||
version "3.7.2"
|
version "3.7.2"
|
||||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
||||||
|
@ -8623,11 +8564,6 @@ cacheable-request@^7.0.2:
|
||||||
normalize-url "^6.0.1"
|
normalize-url "^6.0.1"
|
||||||
responselike "^2.0.0"
|
responselike "^2.0.0"
|
||||||
|
|
||||||
cachedir@^2.3.0:
|
|
||||||
version "2.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8"
|
|
||||||
integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==
|
|
||||||
|
|
||||||
call-bind@^1.0.0, call-bind@^1.0.2:
|
call-bind@^1.0.0, call-bind@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
|
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
|
||||||
|
@ -8761,7 +8697,7 @@ check-error@^1.0.2:
|
||||||
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
|
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
|
||||||
integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==
|
integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==
|
||||||
|
|
||||||
check-more-types@2.24.0, check-more-types@^2.24.0:
|
check-more-types@2.24.0:
|
||||||
version "2.24.0"
|
version "2.24.0"
|
||||||
resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600"
|
resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600"
|
||||||
integrity sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==
|
integrity sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==
|
||||||
|
@ -8868,23 +8804,6 @@ cli-spinners@^2.5.0:
|
||||||
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.7.0.tgz#f815fd30b5f9eaac02db604c7a231ed7cb2f797a"
|
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.7.0.tgz#f815fd30b5f9eaac02db604c7a231ed7cb2f797a"
|
||||||
integrity sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==
|
integrity sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==
|
||||||
|
|
||||||
cli-table3@~0.6.1:
|
|
||||||
version "0.6.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2"
|
|
||||||
integrity sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==
|
|
||||||
dependencies:
|
|
||||||
string-width "^4.2.0"
|
|
||||||
optionalDependencies:
|
|
||||||
"@colors/colors" "1.5.0"
|
|
||||||
|
|
||||||
cli-truncate@^2.1.0:
|
|
||||||
version "2.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7"
|
|
||||||
integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==
|
|
||||||
dependencies:
|
|
||||||
slice-ansi "^3.0.0"
|
|
||||||
string-width "^4.2.0"
|
|
||||||
|
|
||||||
cli-truncate@^3.1.0:
|
cli-truncate@^3.1.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389"
|
resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389"
|
||||||
|
@ -9077,7 +8996,7 @@ colord@^2.9.1:
|
||||||
resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43"
|
resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43"
|
||||||
integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==
|
integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==
|
||||||
|
|
||||||
colorette@2.0.19, colorette@^2.0.14, colorette@^2.0.16, colorette@^2.0.7:
|
colorette@2.0.19, colorette@^2.0.14, colorette@^2.0.7:
|
||||||
version "2.0.19"
|
version "2.0.19"
|
||||||
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798"
|
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798"
|
||||||
integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==
|
integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==
|
||||||
|
@ -9170,11 +9089,6 @@ commander@^9.1.0, commander@^9.4.0, commander@^9.4.1:
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30"
|
resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30"
|
||||||
integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==
|
integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==
|
||||||
|
|
||||||
common-tags@^1.8.0:
|
|
||||||
version "1.8.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6"
|
|
||||||
integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==
|
|
||||||
|
|
||||||
commondir@^1.0.1:
|
commondir@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
|
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
|
||||||
|
@ -9815,70 +9729,6 @@ cwd@^0.10.0:
|
||||||
find-pkg "^0.1.2"
|
find-pkg "^0.1.2"
|
||||||
fs-exists-sync "^0.1.0"
|
fs-exists-sync "^0.1.0"
|
||||||
|
|
||||||
cypress-multi-reporters@^1.6.0:
|
|
||||||
version "1.6.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/cypress-multi-reporters/-/cypress-multi-reporters-1.6.2.tgz#129dfeffa00d4deca3e9f58d84570b9962c28c2b"
|
|
||||||
integrity sha512-lvwGwHqZG5CwGxBJ6UJXWaxlWGkJgxBjP0h+IVLrrwRlJpT4coSwwt+UzMdeqEMrzT4IDfhbtmUNOiDleisOYA==
|
|
||||||
dependencies:
|
|
||||||
debug "^4.1.1"
|
|
||||||
lodash "^4.17.15"
|
|
||||||
|
|
||||||
cypress-terminal-report@^1.4.1:
|
|
||||||
version "1.4.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/cypress-terminal-report/-/cypress-terminal-report-1.4.2.tgz#4eeaf2c6a063b42271ec686aff4ab0d6f7b252a6"
|
|
||||||
integrity sha512-YfKB1McG/1mxTrSTyCxv103hg+NC4atHLw3rZKfeRO4qyL5OLNLKbC6kMErqlTrKjfb/cR6KZ+yNr2G+i4pIJA==
|
|
||||||
dependencies:
|
|
||||||
chalk "^3.0.0"
|
|
||||||
methods "^1.1.2"
|
|
||||||
|
|
||||||
cypress@^9.3.1:
|
|
||||||
version "9.7.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/cypress/-/cypress-9.7.0.tgz#bf55b2afd481f7a113ef5604aa8b693564b5e744"
|
|
||||||
integrity sha512-+1EE1nuuuwIt/N1KXRR2iWHU+OiIt7H28jJDyyI4tiUftId/DrXYEwoDa5+kH2pki1zxnA0r6HrUGHV5eLbF5Q==
|
|
||||||
dependencies:
|
|
||||||
"@cypress/request" "^2.88.10"
|
|
||||||
"@cypress/xvfb" "^1.2.4"
|
|
||||||
"@types/node" "^14.14.31"
|
|
||||||
"@types/sinonjs__fake-timers" "8.1.1"
|
|
||||||
"@types/sizzle" "^2.3.2"
|
|
||||||
arch "^2.2.0"
|
|
||||||
blob-util "^2.0.2"
|
|
||||||
bluebird "^3.7.2"
|
|
||||||
buffer "^5.6.0"
|
|
||||||
cachedir "^2.3.0"
|
|
||||||
chalk "^4.1.0"
|
|
||||||
check-more-types "^2.24.0"
|
|
||||||
cli-cursor "^3.1.0"
|
|
||||||
cli-table3 "~0.6.1"
|
|
||||||
commander "^5.1.0"
|
|
||||||
common-tags "^1.8.0"
|
|
||||||
dayjs "^1.10.4"
|
|
||||||
debug "^4.3.2"
|
|
||||||
enquirer "^2.3.6"
|
|
||||||
eventemitter2 "^6.4.3"
|
|
||||||
execa "4.1.0"
|
|
||||||
executable "^4.1.1"
|
|
||||||
extract-zip "2.0.1"
|
|
||||||
figures "^3.2.0"
|
|
||||||
fs-extra "^9.1.0"
|
|
||||||
getos "^3.2.1"
|
|
||||||
is-ci "^3.0.0"
|
|
||||||
is-installed-globally "~0.4.0"
|
|
||||||
lazy-ass "^1.6.0"
|
|
||||||
listr2 "^3.8.3"
|
|
||||||
lodash "^4.17.21"
|
|
||||||
log-symbols "^4.0.0"
|
|
||||||
minimist "^1.2.6"
|
|
||||||
ospath "^1.2.2"
|
|
||||||
pretty-bytes "^5.6.0"
|
|
||||||
proxy-from-env "1.0.0"
|
|
||||||
request-progress "^3.0.0"
|
|
||||||
semver "^7.3.2"
|
|
||||||
supports-color "^8.1.1"
|
|
||||||
tmp "~0.2.1"
|
|
||||||
untildify "^4.0.0"
|
|
||||||
yauzl "^2.10.0"
|
|
||||||
|
|
||||||
dargs@^7.0.0:
|
dargs@^7.0.0:
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc"
|
resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc"
|
||||||
|
@ -11022,7 +10872,7 @@ enhanced-resolve@^5.8.3:
|
||||||
graceful-fs "^4.2.4"
|
graceful-fs "^4.2.4"
|
||||||
tapable "^2.2.0"
|
tapable "^2.2.0"
|
||||||
|
|
||||||
enquirer@^2.3.5, enquirer@^2.3.6, enquirer@~2.3.6:
|
enquirer@^2.3.5, enquirer@~2.3.6:
|
||||||
version "2.3.6"
|
version "2.3.6"
|
||||||
resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d"
|
resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d"
|
||||||
integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==
|
integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==
|
||||||
|
@ -11523,13 +11373,6 @@ escodegen@^2.0.0:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
source-map "~0.6.1"
|
source-map "~0.6.1"
|
||||||
|
|
||||||
eslint-plugin-cypress@^2.11.3:
|
|
||||||
version "2.12.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/eslint-plugin-cypress/-/eslint-plugin-cypress-2.12.1.tgz#9aeee700708ca8c058e00cdafe215199918c2632"
|
|
||||||
integrity sha512-c2W/uPADl5kospNDihgiLc7n87t5XhUbFDoTl6CfVkmG+kDAb5Ux10V9PoLPu9N+r7znpc+iQlcmAqT1A/89HA==
|
|
||||||
dependencies:
|
|
||||||
globals "^11.12.0"
|
|
||||||
|
|
||||||
eslint-plugin-svelte@^2.32.2:
|
eslint-plugin-svelte@^2.32.2:
|
||||||
version "2.32.2"
|
version "2.32.2"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-plugin-svelte/-/eslint-plugin-svelte-2.32.2.tgz#d8f1352b55967445ee8d57aaee55f99712696a30"
|
resolved "https://registry.yarnpkg.com/eslint-plugin-svelte/-/eslint-plugin-svelte-2.32.2.tgz#d8f1352b55967445ee8d57aaee55f99712696a30"
|
||||||
|
@ -11882,11 +11725,6 @@ event-target-shim@^5.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
|
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
|
||||||
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
|
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
|
||||||
|
|
||||||
eventemitter2@^6.4.3:
|
|
||||||
version "6.4.9"
|
|
||||||
resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.9.tgz#41f2750781b4230ed58827bc119d293471ecb125"
|
|
||||||
integrity sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==
|
|
||||||
|
|
||||||
eventemitter3@^4.0.4:
|
eventemitter3@^4.0.4:
|
||||||
version "4.0.7"
|
version "4.0.7"
|
||||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
||||||
|
@ -11910,21 +11748,6 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
|
||||||
md5.js "^1.3.4"
|
md5.js "^1.3.4"
|
||||||
safe-buffer "^5.1.1"
|
safe-buffer "^5.1.1"
|
||||||
|
|
||||||
execa@4.1.0:
|
|
||||||
version "4.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a"
|
|
||||||
integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==
|
|
||||||
dependencies:
|
|
||||||
cross-spawn "^7.0.0"
|
|
||||||
get-stream "^5.0.0"
|
|
||||||
human-signals "^1.1.1"
|
|
||||||
is-stream "^2.0.0"
|
|
||||||
merge-stream "^2.0.0"
|
|
||||||
npm-run-path "^4.0.0"
|
|
||||||
onetime "^5.1.0"
|
|
||||||
signal-exit "^3.0.2"
|
|
||||||
strip-final-newline "^2.0.0"
|
|
||||||
|
|
||||||
execa@5.0.0:
|
execa@5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376"
|
resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376"
|
||||||
|
@ -11981,13 +11804,6 @@ execa@^1.0.0:
|
||||||
signal-exit "^3.0.0"
|
signal-exit "^3.0.0"
|
||||||
strip-eof "^1.0.0"
|
strip-eof "^1.0.0"
|
||||||
|
|
||||||
executable@^4.1.1:
|
|
||||||
version "4.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c"
|
|
||||||
integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==
|
|
||||||
dependencies:
|
|
||||||
pify "^2.2.0"
|
|
||||||
|
|
||||||
exif-parser@^0.1.12:
|
exif-parser@^0.1.12:
|
||||||
version "0.1.12"
|
version "0.1.12"
|
||||||
resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922"
|
resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922"
|
||||||
|
@ -12179,17 +11995,6 @@ extglob@^2.0.4:
|
||||||
snapdragon "^0.8.1"
|
snapdragon "^0.8.1"
|
||||||
to-regex "^3.0.1"
|
to-regex "^3.0.1"
|
||||||
|
|
||||||
extract-zip@2.0.1:
|
|
||||||
version "2.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a"
|
|
||||||
integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==
|
|
||||||
dependencies:
|
|
||||||
debug "^4.1.1"
|
|
||||||
get-stream "^5.1.0"
|
|
||||||
yauzl "^2.10.0"
|
|
||||||
optionalDependencies:
|
|
||||||
"@types/yauzl" "^2.9.1"
|
|
||||||
|
|
||||||
extsprintf@1.3.0:
|
extsprintf@1.3.0:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
|
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
|
||||||
|
@ -12376,7 +12181,7 @@ fflate@^0.4.1:
|
||||||
resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.4.8.tgz#f90b82aefbd8ac174213abb338bd7ef848f0f5ae"
|
resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.4.8.tgz#f90b82aefbd8ac174213abb338bd7ef848f0f5ae"
|
||||||
integrity sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==
|
integrity sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==
|
||||||
|
|
||||||
figures@3.2.0, figures@^3.0.0, figures@^3.2.0:
|
figures@3.2.0, figures@^3.0.0:
|
||||||
version "3.2.0"
|
version "3.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af"
|
resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af"
|
||||||
integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==
|
integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==
|
||||||
|
@ -13114,7 +12919,7 @@ get-stream@^4.0.0, get-stream@^4.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
pump "^3.0.0"
|
pump "^3.0.0"
|
||||||
|
|
||||||
get-stream@^5.0.0, get-stream@^5.1.0:
|
get-stream@^5.1.0:
|
||||||
version "5.2.0"
|
version "5.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
|
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
|
||||||
integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
|
integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
|
||||||
|
@ -13168,13 +12973,6 @@ getopts@2.3.0:
|
||||||
resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.3.0.tgz#71e5593284807e03e2427449d4f6712a268666f4"
|
resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.3.0.tgz#71e5593284807e03e2427449d4f6712a268666f4"
|
||||||
integrity sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==
|
integrity sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==
|
||||||
|
|
||||||
getos@^3.2.1:
|
|
||||||
version "3.2.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/getos/-/getos-3.2.1.tgz#0134d1f4e00eb46144c5a9c0ac4dc087cbb27dc5"
|
|
||||||
integrity sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==
|
|
||||||
dependencies:
|
|
||||||
async "^3.2.0"
|
|
||||||
|
|
||||||
getpass@^0.1.1:
|
getpass@^0.1.1:
|
||||||
version "0.1.7"
|
version "0.1.7"
|
||||||
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
|
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
|
||||||
|
@ -13385,7 +13183,7 @@ global@~4.4.0:
|
||||||
min-document "^2.19.0"
|
min-document "^2.19.0"
|
||||||
process "^0.11.10"
|
process "^0.11.10"
|
||||||
|
|
||||||
globals@^11.1.0, globals@^11.12.0:
|
globals@^11.1.0:
|
||||||
version "11.12.0"
|
version "11.12.0"
|
||||||
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
||||||
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
|
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
|
||||||
|
@ -13996,15 +13794,6 @@ http-signature@~1.2.0:
|
||||||
jsprim "^1.2.2"
|
jsprim "^1.2.2"
|
||||||
sshpk "^1.7.0"
|
sshpk "^1.7.0"
|
||||||
|
|
||||||
http-signature@~1.3.6:
|
|
||||||
version "1.3.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.6.tgz#cb6fbfdf86d1c974f343be94e87f7fc128662cf9"
|
|
||||||
integrity sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==
|
|
||||||
dependencies:
|
|
||||||
assert-plus "^1.0.0"
|
|
||||||
jsprim "^2.0.2"
|
|
||||||
sshpk "^1.14.1"
|
|
||||||
|
|
||||||
http2-wrapper@^1.0.0-beta.5.2:
|
http2-wrapper@^1.0.0-beta.5.2:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d"
|
resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d"
|
||||||
|
@ -14021,11 +13810,6 @@ https-proxy-agent@5, https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1:
|
||||||
agent-base "6"
|
agent-base "6"
|
||||||
debug "4"
|
debug "4"
|
||||||
|
|
||||||
human-signals@^1.1.1:
|
|
||||||
version "1.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
|
|
||||||
integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==
|
|
||||||
|
|
||||||
human-signals@^2.1.0:
|
human-signals@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
|
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
|
||||||
|
@ -14512,7 +14296,7 @@ is-callable@^1.1.4, is-callable@^1.2.4:
|
||||||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945"
|
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945"
|
||||||
integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==
|
integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==
|
||||||
|
|
||||||
is-ci@3.0.1, is-ci@^3.0.0:
|
is-ci@3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867"
|
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867"
|
||||||
integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==
|
integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==
|
||||||
|
@ -14650,7 +14434,7 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-extglob "^2.1.1"
|
is-extglob "^2.1.1"
|
||||||
|
|
||||||
is-installed-globally@^0.4.0, is-installed-globally@~0.4.0:
|
is-installed-globally@^0.4.0:
|
||||||
version "0.4.0"
|
version "0.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520"
|
resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520"
|
||||||
integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==
|
integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==
|
||||||
|
@ -15494,10 +15278,10 @@ jest-snapshot@^29.6.2:
|
||||||
pretty-format "^29.6.2"
|
pretty-format "^29.6.2"
|
||||||
semver "^7.5.3"
|
semver "^7.5.3"
|
||||||
|
|
||||||
jest-util@^29.0.0:
|
jest-util@^29.0.0, jest-util@^29.6.2:
|
||||||
version "29.6.1"
|
version "29.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.1.tgz#c9e29a87a6edbf1e39e6dee2b4689b8a146679cb"
|
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.2.tgz#8a052df8fff2eebe446769fd88814521a517664d"
|
||||||
integrity sha512-NRFCcjc+/uO3ijUVyNOQJluf8PtGCe/W6cix36+M3cTFgiYqFOOW5MgN4JOOcvbUhcKTYVd1CvHz/LWi8d16Mg==
|
integrity sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@jest/types" "^29.6.1"
|
"@jest/types" "^29.6.1"
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
@ -15518,18 +15302,6 @@ jest-util@^29.4.3:
|
||||||
graceful-fs "^4.2.9"
|
graceful-fs "^4.2.9"
|
||||||
picomatch "^2.2.3"
|
picomatch "^2.2.3"
|
||||||
|
|
||||||
jest-util@^29.6.2:
|
|
||||||
version "29.6.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.2.tgz#8a052df8fff2eebe446769fd88814521a517664d"
|
|
||||||
integrity sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w==
|
|
||||||
dependencies:
|
|
||||||
"@jest/types" "^29.6.1"
|
|
||||||
"@types/node" "*"
|
|
||||||
chalk "^4.0.0"
|
|
||||||
ci-info "^3.2.0"
|
|
||||||
graceful-fs "^4.2.9"
|
|
||||||
picomatch "^2.2.3"
|
|
||||||
|
|
||||||
jest-validate@^29.6.2:
|
jest-validate@^29.6.2:
|
||||||
version "29.6.2"
|
version "29.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.6.2.tgz#25d972af35b2415b83b1373baf1a47bb266c1082"
|
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.6.2.tgz#25d972af35b2415b83b1373baf1a47bb266c1082"
|
||||||
|
@ -15918,16 +15690,6 @@ jsprim@^1.2.2:
|
||||||
json-schema "0.4.0"
|
json-schema "0.4.0"
|
||||||
verror "1.10.0"
|
verror "1.10.0"
|
||||||
|
|
||||||
jsprim@^2.0.2:
|
|
||||||
version "2.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-2.0.2.tgz#77ca23dbcd4135cd364800d22ff82c2185803d4d"
|
|
||||||
integrity sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==
|
|
||||||
dependencies:
|
|
||||||
assert-plus "1.0.0"
|
|
||||||
extsprintf "1.3.0"
|
|
||||||
json-schema "0.4.0"
|
|
||||||
verror "1.10.0"
|
|
||||||
|
|
||||||
jstransform@~11.0.0:
|
jstransform@~11.0.0:
|
||||||
version "11.0.3"
|
version "11.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/jstransform/-/jstransform-11.0.3.tgz#09a78993e0ae4d4ef4487f6155a91f6190cb4223"
|
resolved "https://registry.yarnpkg.com/jstransform/-/jstransform-11.0.3.tgz#09a78993e0ae4d4ef4487f6155a91f6190cb4223"
|
||||||
|
@ -16307,7 +16069,7 @@ latest-version@^5.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
package-json "^6.3.0"
|
package-json "^6.3.0"
|
||||||
|
|
||||||
lazy-ass@1.6.0, lazy-ass@^1.6.0:
|
lazy-ass@1.6.0:
|
||||||
version "1.6.0"
|
version "1.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513"
|
resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513"
|
||||||
integrity sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==
|
integrity sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==
|
||||||
|
@ -16665,20 +16427,6 @@ linkify-it@^3.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
uc.micro "^1.0.1"
|
uc.micro "^1.0.1"
|
||||||
|
|
||||||
listr2@^3.8.3:
|
|
||||||
version "3.14.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e"
|
|
||||||
integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==
|
|
||||||
dependencies:
|
|
||||||
cli-truncate "^2.1.0"
|
|
||||||
colorette "^2.0.16"
|
|
||||||
log-update "^4.0.0"
|
|
||||||
p-map "^4.0.0"
|
|
||||||
rfdc "^1.3.0"
|
|
||||||
rxjs "^7.5.1"
|
|
||||||
through "^2.3.8"
|
|
||||||
wrap-ansi "^7.0.0"
|
|
||||||
|
|
||||||
load-bmfont@^1.3.1, load-bmfont@^1.4.0:
|
load-bmfont@^1.3.1, load-bmfont@^1.4.0:
|
||||||
version "1.4.1"
|
version "1.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.1.tgz#c0f5f4711a1e2ccff725a7b6078087ccfcddd3e9"
|
resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.1.tgz#c0f5f4711a1e2ccff725a7b6078087ccfcddd3e9"
|
||||||
|
@ -16894,7 +16642,7 @@ lodash.omit@^4.5.0:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60"
|
resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60"
|
||||||
integrity sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==
|
integrity sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==
|
||||||
|
|
||||||
lodash.once@^4.0.0, lodash.once@^4.1.1:
|
lodash.once@^4.0.0:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
||||||
integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==
|
integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==
|
||||||
|
@ -16946,7 +16694,7 @@ log-symbols@^3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
chalk "^2.4.2"
|
chalk "^2.4.2"
|
||||||
|
|
||||||
log-symbols@^4.0.0, log-symbols@^4.1.0:
|
log-symbols@^4.1.0:
|
||||||
version "4.1.0"
|
version "4.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
|
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
|
||||||
integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==
|
integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==
|
||||||
|
@ -16954,16 +16702,6 @@ log-symbols@^4.0.0, log-symbols@^4.1.0:
|
||||||
chalk "^4.1.0"
|
chalk "^4.1.0"
|
||||||
is-unicode-supported "^0.1.0"
|
is-unicode-supported "^0.1.0"
|
||||||
|
|
||||||
log-update@^4.0.0:
|
|
||||||
version "4.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1"
|
|
||||||
integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==
|
|
||||||
dependencies:
|
|
||||||
ansi-escapes "^4.3.0"
|
|
||||||
cli-cursor "^3.1.0"
|
|
||||||
slice-ansi "^4.0.0"
|
|
||||||
wrap-ansi "^6.2.0"
|
|
||||||
|
|
||||||
logform@^2.3.2, logform@^2.4.0:
|
logform@^2.3.2, logform@^2.4.0:
|
||||||
version "2.5.1"
|
version "2.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/logform/-/logform-2.5.1.tgz#44c77c34becd71b3a42a3970c77929e52c6ed48b"
|
resolved "https://registry.yarnpkg.com/logform/-/logform-2.5.1.tgz#44c77c34becd71b3a42a3970c77929e52c6ed48b"
|
||||||
|
@ -18497,7 +18235,7 @@ npm-run-path@^2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
path-key "^2.0.0"
|
path-key "^2.0.0"
|
||||||
|
|
||||||
npm-run-path@^4.0.0, npm-run-path@^4.0.1:
|
npm-run-path@^4.0.1:
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
|
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
|
||||||
integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
|
integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
|
||||||
|
@ -19059,11 +18797,6 @@ os-tmpdir@~1.0.2:
|
||||||
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
|
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
|
||||||
integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==
|
integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==
|
||||||
|
|
||||||
ospath@^1.2.2:
|
|
||||||
version "1.2.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b"
|
|
||||||
integrity sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==
|
|
||||||
|
|
||||||
osx-release@^1.0.0:
|
osx-release@^1.0.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/osx-release/-/osx-release-1.1.0.tgz#f217911a28136949af1bf9308b241e2737d3cd6c"
|
resolved "https://registry.yarnpkg.com/osx-release/-/osx-release-1.1.0.tgz#f217911a28136949af1bf9308b241e2737d3cd6c"
|
||||||
|
@ -19700,7 +19433,7 @@ pify@5.0.0, pify@^5.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f"
|
resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f"
|
||||||
integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==
|
integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==
|
||||||
|
|
||||||
pify@^2.2.0, pify@^2.3.0:
|
pify@^2.3.0:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
|
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
|
||||||
integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==
|
integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==
|
||||||
|
@ -20625,11 +20358,6 @@ prettier@^2.5.1:
|
||||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.4.tgz#34dd2595629bfbb79d344ac4a91ff948694463c3"
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.4.tgz#34dd2595629bfbb79d344ac4a91ff948694463c3"
|
||||||
integrity sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==
|
integrity sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==
|
||||||
|
|
||||||
pretty-bytes@^5.6.0:
|
|
||||||
version "5.6.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
|
|
||||||
integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==
|
|
||||||
|
|
||||||
pretty-format@^26.6.2:
|
pretty-format@^26.6.2:
|
||||||
version "26.6.2"
|
version "26.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93"
|
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93"
|
||||||
|
@ -20865,11 +20593,6 @@ proxy-agent@^5.0.0:
|
||||||
proxy-from-env "^1.0.0"
|
proxy-from-env "^1.0.0"
|
||||||
socks-proxy-agent "^5.0.0"
|
socks-proxy-agent "^5.0.0"
|
||||||
|
|
||||||
proxy-from-env@1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee"
|
|
||||||
integrity sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==
|
|
||||||
|
|
||||||
proxy-from-env@^1.0.0, proxy-from-env@^1.1.0:
|
proxy-from-env@^1.0.0, proxy-from-env@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
|
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
|
||||||
|
@ -20983,13 +20706,6 @@ qs@6.11.0, qs@^6.10.3, qs@^6.11.0, qs@^6.4.0, qs@^6.9.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
side-channel "^1.0.4"
|
side-channel "^1.0.4"
|
||||||
|
|
||||||
qs@~6.10.3:
|
|
||||||
version "6.10.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.5.tgz#974715920a80ff6a262264acd2c7e6c2a53282b4"
|
|
||||||
integrity sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ==
|
|
||||||
dependencies:
|
|
||||||
side-channel "^1.0.4"
|
|
||||||
|
|
||||||
qs@~6.5.2:
|
qs@~6.5.2:
|
||||||
version "6.5.3"
|
version "6.5.3"
|
||||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
|
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
|
||||||
|
@ -21544,13 +21260,6 @@ repeat-string@^1.6.1:
|
||||||
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
|
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
|
||||||
integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==
|
integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==
|
||||||
|
|
||||||
request-progress@^3.0.0:
|
|
||||||
version "3.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe"
|
|
||||||
integrity sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==
|
|
||||||
dependencies:
|
|
||||||
throttleit "^1.0.0"
|
|
||||||
|
|
||||||
request@^2.88.0:
|
request@^2.88.0:
|
||||||
version "2.88.2"
|
version "2.88.2"
|
||||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
||||||
|
@ -21983,7 +21692,7 @@ rxjs@^6.6.0, rxjs@^6.6.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "^1.9.0"
|
tslib "^1.9.0"
|
||||||
|
|
||||||
rxjs@^7.0.0, rxjs@^7.5.1, rxjs@^7.5.5, rxjs@^7.8.0:
|
rxjs@^7.0.0, rxjs@^7.5.5, rxjs@^7.8.0:
|
||||||
version "7.8.0"
|
version "7.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4"
|
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4"
|
||||||
integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==
|
integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==
|
||||||
|
@ -22502,15 +22211,6 @@ slice-ansi@^2.1.0:
|
||||||
astral-regex "^1.0.0"
|
astral-regex "^1.0.0"
|
||||||
is-fullwidth-code-point "^2.0.0"
|
is-fullwidth-code-point "^2.0.0"
|
||||||
|
|
||||||
slice-ansi@^3.0.0:
|
|
||||||
version "3.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787"
|
|
||||||
integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==
|
|
||||||
dependencies:
|
|
||||||
ansi-styles "^4.0.0"
|
|
||||||
astral-regex "^2.0.0"
|
|
||||||
is-fullwidth-code-point "^3.0.0"
|
|
||||||
|
|
||||||
slice-ansi@^4.0.0:
|
slice-ansi@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b"
|
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b"
|
||||||
|
@ -22945,7 +22645,7 @@ ssh2@^1.11.0:
|
||||||
cpu-features "~0.0.4"
|
cpu-features "~0.0.4"
|
||||||
nan "^2.16.0"
|
nan "^2.16.0"
|
||||||
|
|
||||||
sshpk@^1.14.1, sshpk@^1.7.0:
|
sshpk@^1.7.0:
|
||||||
version "1.17.0"
|
version "1.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5"
|
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5"
|
||||||
integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==
|
integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==
|
||||||
|
@ -23451,7 +23151,7 @@ supports-color@^7.0.0, supports-color@^7.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
has-flag "^4.0.0"
|
has-flag "^4.0.0"
|
||||||
|
|
||||||
supports-color@^8.0.0, supports-color@^8.1.0, supports-color@^8.1.1:
|
supports-color@^8.0.0, supports-color@^8.1.0:
|
||||||
version "8.1.1"
|
version "8.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
|
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
|
||||||
integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
|
integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
|
||||||
|
@ -23902,11 +23602,6 @@ thread-stream@^2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
real-require "^0.2.0"
|
real-require "^0.2.0"
|
||||||
|
|
||||||
throttleit@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c"
|
|
||||||
integrity sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==
|
|
||||||
|
|
||||||
through2@3.0.2:
|
through2@3.0.2:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.2.tgz#99f88931cfc761ec7678b41d5d7336b5b6a07bf4"
|
resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.2.tgz#99f88931cfc761ec7678b41d5d7336b5b6a07bf4"
|
||||||
|
@ -25792,7 +25487,7 @@ yargs@^17.2.1, yargs@^17.3.1, yargs@^17.5.1, yargs@^17.6.2:
|
||||||
y18n "^5.0.5"
|
y18n "^5.0.5"
|
||||||
yargs-parser "^21.1.1"
|
yargs-parser "^21.1.1"
|
||||||
|
|
||||||
yauzl@^2.10.0, yauzl@^2.4.2:
|
yauzl@^2.4.2:
|
||||||
version "2.10.0"
|
version "2.10.0"
|
||||||
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
|
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
|
||||||
integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==
|
integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==
|
||||||
|
|
Loading…
Reference in New Issue