diff --git a/.github/workflows/deploy-cloud.yaml b/.github/workflows/deploy-cloud.yaml index fa80da846f..5bc3f0bbca 100644 --- a/.github/workflows/deploy-cloud.yaml +++ b/.github/workflows/deploy-cloud.yaml @@ -55,7 +55,7 @@ jobs: config-files: values.production.yaml chart-path: charts/budibase namespace: budibase - values: globals.appVersion=v${{ env.RELEASE_VERSION }},services.couchdb.url=${{ secrets.PRODUCTION_COUCHDB_URL }},services.couchdb.password=${{ secrets.PRODUCTION_COUCHDB_PASSWORD }} + values: globals.appVersion=${{ env.RELEASE_VERSION }},services.couchdb.url=${{ secrets.PRODUCTION_COUCHDB_URL }},services.couchdb.password=${{ secrets.PRODUCTION_COUCHDB_PASSWORD }} name: budibase-prod - name: Discord Webhook Action diff --git a/charts/budibase/templates/app-service-deployment.yaml b/charts/budibase/templates/app-service-deployment.yaml index 6ba9337f5b..e7abf82de0 100644 --- a/charts/budibase/templates/app-service-deployment.yaml +++ b/charts/budibase/templates/app-service-deployment.yaml @@ -199,7 +199,11 @@ spec: value: {{ .Values.services.tlsRejectUnauthorized }} {{ end }} - image: budibase/apps:{{ .Values.globals.appVersion }} + {{ if .Values.globals.appVersion }} + image: budibase/apps:v{{ .Values.globals.appVersion }} + {{ else }} + image: budibase/apps:v{{ .Chart.AppVersion }} + {{ end }} imagePullPolicy: Always livenessProbe: httpGet: diff --git a/charts/budibase/templates/proxy-service-deployment.yaml b/charts/budibase/templates/proxy-service-deployment.yaml index 42af458a8c..191f892565 100644 --- a/charts/budibase/templates/proxy-service-deployment.yaml +++ b/charts/budibase/templates/proxy-service-deployment.yaml @@ -37,7 +37,11 @@ spec: {{ end }} spec: containers: - - image: budibase/proxy:{{ .Values.globals.appVersion }} + {{ if .Values.globals.appVersion }} + image: budibase/proxy:v{{ .Values.globals.appVersion }} + {{ else }} + image: budibase/proxy:v{{ .Chart.AppVersion }} + {{ end }} imagePullPolicy: Always name: proxy-service ports: diff --git a/charts/budibase/templates/worker-service-deployment.yaml b/charts/budibase/templates/worker-service-deployment.yaml index 0df295b5d6..69f864cfc0 100644 --- a/charts/budibase/templates/worker-service-deployment.yaml +++ b/charts/budibase/templates/worker-service-deployment.yaml @@ -189,7 +189,11 @@ spec: value: {{ .Values.services.tlsRejectUnauthorized }} {{ end }} - image: budibase/worker:{{ .Values.globals.appVersion }} + {{ if .Values.globals.appVersion }} + image: budibase/worker:v{{ .Values.globals.appVersion }} + {{ else }} + image: budibase/worker:v{{ .Chart.AppVersion }} + {{ end }} imagePullPolicy: Always livenessProbe: httpGet: diff --git a/charts/budibase/values.yaml b/charts/budibase/values.yaml index dbf6b6b46e..2d89e81b7f 100644 --- a/charts/budibase/values.yaml +++ b/charts/budibase/values.yaml @@ -74,7 +74,7 @@ tolerations: [] affinity: {} globals: - appVersion: "latest" + appVersion: "" # Use as an override to .Chart.AppVersion budibaseEnv: PRODUCTION tenantFeatureFlags: "*:LICENSING,*:USER_GROUPS,*:ONBOARDING_TOUR" enableAnalytics: "1" diff --git a/lerna.json b/lerna.json index ec62402383..19f4e3e40b 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.4.44-alpha.11", + "version": "2.4.44-alpha.16", "npmClient": "yarn", "packages": ["packages/*"], "command": { diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index e49cdafe68..6110e6d461 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "2.4.44-alpha.11", + "version": "2.4.44-alpha.16", "description": "Budibase backend core libraries used in server and worker", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -24,7 +24,7 @@ "dependencies": { "@budibase/nano": "10.1.2", "@budibase/pouchdb-replication-stream": "1.2.10", - "@budibase/types": "2.4.44-alpha.11", + "@budibase/types": "2.4.44-alpha.16", "@shopify/jest-koa-mocks": "5.0.1", "@techpass/passport-openidconnect": "0.3.2", "aws-cloudfront-sign": "2.2.0", @@ -58,6 +58,7 @@ "zlib": "1.0.5" }, "devDependencies": { + "@jest/test-sequencer": "29.5.0", "@swc/core": "^1.3.25", "@swc/jest": "^0.2.24", "@trendyol/jest-testcontainers": "^2.1.1", @@ -75,14 +76,14 @@ "@types/uuid": "8.3.4", "chance": "1.1.8", "ioredis-mock": "5.8.0", - "jest": "28.1.1", + "jest": "29.5.0", "jest-serial-runner": "^1.2.1", "koa": "2.13.4", "nodemon": "2.0.16", "pino-pretty": "10.0.0", "pouchdb-adapter-memory": "7.2.2", "timekeeper": "2.2.0", - "ts-jest": "28.0.4", + "ts-jest": "29.0.5", "ts-node": "10.8.1", "tsconfig-paths": "4.0.0", "typescript": "4.7.3" diff --git a/packages/backend-core/src/auth/tests/auth.spec.ts b/packages/backend-core/src/auth/tests/auth.spec.ts index 307f6a63c8..3ae691be58 100644 --- a/packages/backend-core/src/auth/tests/auth.spec.ts +++ b/packages/backend-core/src/auth/tests/auth.spec.ts @@ -1,4 +1,5 @@ -import { structures, testEnv } from "../../../tests" +import { structures } from "../../../tests" +import { testEnv } from "../../../tests/extra" import * as auth from "../auth" import * as events from "../../events" diff --git a/packages/backend-core/src/cache/tests/writethrough.spec.ts b/packages/backend-core/src/cache/tests/writethrough.spec.ts index 363344c84d..e4c7cc6e64 100644 --- a/packages/backend-core/src/cache/tests/writethrough.spec.ts +++ b/packages/backend-core/src/cache/tests/writethrough.spec.ts @@ -1,6 +1,6 @@ +import { DBTestConfiguration } from "../../../tests/extra" import { structures, - DBTestConfiguration, expectFunctionWasCalledTimesWith, mocks, } from "../../../tests" diff --git a/packages/backend-core/src/configs/tests/configs.spec.ts b/packages/backend-core/src/configs/tests/configs.spec.ts index 45e56a2581..2c6a1948ec 100644 --- a/packages/backend-core/src/configs/tests/configs.spec.ts +++ b/packages/backend-core/src/configs/tests/configs.spec.ts @@ -1,9 +1,5 @@ -import { - DBTestConfiguration, - generator, - testEnv, - structures, -} from "../../../tests" +import { generator, structures } from "../../../tests" +import { DBTestConfiguration, testEnv } from "../../../tests/extra" import { ConfigType } from "@budibase/types" import env from "../../environment" import * as configs from "../configs" diff --git a/packages/backend-core/src/context/mainContext.ts b/packages/backend-core/src/context/mainContext.ts index e1bd535b78..2f66c4bb7d 100644 --- a/packages/backend-core/src/context/mainContext.ts +++ b/packages/backend-core/src/context/mainContext.ts @@ -2,7 +2,7 @@ // store an app ID to pretend there is a context import env from "../environment" import Context from "./Context" -import * as conversions from "../db/conversions" +import * as conversions from "../docIds/conversions" import { getDB } from "../db/db" import { DocumentType, @@ -43,8 +43,12 @@ export function baseGlobalDBName(tenantId: string | undefined | null) { } } +export function getPlatformURL() { + return env.PLATFORM_URL +} + export function isMultiTenant() { - return env.MULTI_TENANCY + return !!env.MULTI_TENANCY } export function isTenantIdSet() { diff --git a/packages/backend-core/src/context/tests/index.spec.ts b/packages/backend-core/src/context/tests/index.spec.ts index 3f760d4a49..d8bb598af1 100644 --- a/packages/backend-core/src/context/tests/index.spec.ts +++ b/packages/backend-core/src/context/tests/index.spec.ts @@ -1,4 +1,4 @@ -import { testEnv } from "../../../tests" +import { testEnv } from "../../../tests/extra" import * as context from "../" import { DEFAULT_TENANT_ID } from "../../constants" diff --git a/packages/backend-core/src/db/couch/DatabaseImpl.ts b/packages/backend-core/src/db/couch/DatabaseImpl.ts index a3a398950b..94d78e94ff 100644 --- a/packages/backend-core/src/db/couch/DatabaseImpl.ts +++ b/packages/backend-core/src/db/couch/DatabaseImpl.ts @@ -15,7 +15,7 @@ import { getCouchInfo } from "./connections" import { directCouchCall } from "./utils" import { getPouchDB } from "./pouchDB" import { WriteStream, ReadStream } from "fs" -import { newid } from "../../newid" +import { newid } from "../../docIds/newid" function buildNano(couchInfo: { url: string; cookie: string }) { return Nano({ diff --git a/packages/backend-core/src/db/index.ts b/packages/backend-core/src/db/index.ts index ea93b91d14..cf71199ecf 100644 --- a/packages/backend-core/src/db/index.ts +++ b/packages/backend-core/src/db/index.ts @@ -2,7 +2,7 @@ export * from "./couch" export * from "./db" export * from "./utils" export * from "./views" -export * from "./conversions" +export * from "../docIds/conversions" export { default as Replication } from "./Replication" // exports to support old export structure export * from "../constants/db" diff --git a/packages/backend-core/src/db/tests/lucene.spec.ts b/packages/backend-core/src/db/tests/lucene.spec.ts index 26ce316a9d..b4791a86e0 100644 --- a/packages/backend-core/src/db/tests/lucene.spec.ts +++ b/packages/backend-core/src/db/tests/lucene.spec.ts @@ -1,4 +1,4 @@ -import { newid } from "../../newid" +import { newid } from "../../docIds/newid" import { getDB } from "../db" import { Database } from "@budibase/types" import { QueryBuilder, paginatedSearch, fullSearch } from "../lucene" diff --git a/packages/backend-core/src/db/tests/utils.spec.ts b/packages/backend-core/src/db/tests/utils.spec.ts index 138457c65e..d9cb09a791 100644 --- a/packages/backend-core/src/db/tests/utils.spec.ts +++ b/packages/backend-core/src/db/tests/utils.spec.ts @@ -3,7 +3,7 @@ import { getProdAppID, isDevAppID, isProdAppID, -} from "../conversions" +} from "../../docIds/conversions" import { generateAppID } from "../utils" describe("utils", () => { diff --git a/packages/backend-core/src/db/utils.ts b/packages/backend-core/src/db/utils.ts index 441c118235..6034296996 100644 --- a/packages/backend-core/src/db/utils.ts +++ b/packages/backend-core/src/db/utils.ts @@ -1,257 +1,12 @@ -import { newid } from "../newid" import env from "../environment" -import { - DEFAULT_TENANT_ID, - SEPARATOR, - DocumentType, - UNICODE_MAX, - ViewName, - InternalTable, - APP_PREFIX, -} from "../constants" +import { DEFAULT_TENANT_ID, SEPARATOR, DocumentType } from "../constants" import { getTenantId, getGlobalDBName } from "../context" import { doWithDB, directCouchAllDbs } from "./db" import { getAppMetadata } from "../cache/appMetadata" -import { isDevApp, isDevAppID, getProdAppID } from "./conversions" +import { isDevApp, isDevAppID, getProdAppID } from "../docIds/conversions" import { App, Database } from "@budibase/types" - -/** - * Generates a new app ID. - * @returns {string} The new app ID which the app doc can be stored under. - */ -export const generateAppID = (tenantId?: string | null) => { - let id = APP_PREFIX - if (tenantId) { - id += `${tenantId}${SEPARATOR}` - } - return `${id}${newid()}` -} - -/** - * If creating DB allDocs/query params with only a single top level ID this can be used, this - * is usually the case as most of our docs are top level e.g. tables, automations, users and so on. - * More complex cases such as link docs and rows which have multiple levels of IDs that their - * ID consists of need their own functions to build the allDocs parameters. - * @param {string} docType The type of document which input params are being built for, e.g. user, - * link, app, table and so on. - * @param {string|null} docId The ID of the document minus its type - this is only needed if looking - * for a singular document. - * @param {object} otherProps Add any other properties onto the request, e.g. include_docs. - * @returns {object} Parameters which can then be used with an allDocs request. - */ -export function getDocParams( - docType: string, - docId?: string | null, - otherProps: any = {} -) { - if (docId == null) { - docId = "" - } - return { - ...otherProps, - startkey: `${docType}${SEPARATOR}${docId}`, - endkey: `${docType}${SEPARATOR}${docId}${UNICODE_MAX}`, - } -} - -/** - * Gets the DB allDocs/query params for retrieving a row. - * @param {string|null} tableId The table in which the rows have been stored. - * @param {string|null} rowId The ID of the row which is being specifically queried for. This can be - * left null to get all the rows in the table. - * @param {object} otherProps Any other properties to add to the request. - * @returns {object} Parameters which can then be used with an allDocs request. - */ -export function getRowParams( - tableId?: string | null, - rowId?: string | null, - otherProps = {} -) { - if (tableId == null) { - return getDocParams(DocumentType.ROW, null, otherProps) - } - - const endOfKey = rowId == null ? `${tableId}${SEPARATOR}` : rowId - - return getDocParams(DocumentType.ROW, endOfKey, otherProps) -} - -/** - * Retrieve the correct index for a view based on default design DB. - */ -export function getQueryIndex(viewName: ViewName) { - return `database/${viewName}` -} - -/** - * Gets a new row ID for the specified table. - * @param {string} tableId The table which the row is being created for. - * @param {string|null} id If an ID is to be used then the UUID can be substituted for this. - * @returns {string} The new ID which a row doc can be stored under. - */ -export function generateRowID(tableId: string, id?: string) { - id = id || newid() - return `${DocumentType.ROW}${SEPARATOR}${tableId}${SEPARATOR}${id}` -} - -/** - * Check if a given ID is that of a table. - * @returns {boolean} - */ -export const isTableId = (id: string) => { - // this includes datasource plus tables - return ( - id && - (id.startsWith(`${DocumentType.TABLE}${SEPARATOR}`) || - id.startsWith(`${DocumentType.DATASOURCE_PLUS}${SEPARATOR}`)) - ) -} - -/** - * Check if a given ID is that of a datasource or datasource plus. - * @returns {boolean} - */ -export const isDatasourceId = (id: string) => { - // this covers both datasources and datasource plus - return id && id.startsWith(`${DocumentType.DATASOURCE}${SEPARATOR}`) -} - -/** - * Generates a new workspace ID. - * @returns {string} The new workspace ID which the workspace doc can be stored under. - */ -export function generateWorkspaceID() { - return `${DocumentType.WORKSPACE}${SEPARATOR}${newid()}` -} - -/** - * Gets parameters for retrieving workspaces. - */ -export function getWorkspaceParams(id = "", otherProps = {}) { - return { - ...otherProps, - startkey: `${DocumentType.WORKSPACE}${SEPARATOR}${id}`, - endkey: `${DocumentType.WORKSPACE}${SEPARATOR}${id}${UNICODE_MAX}`, - } -} - -/** - * Generates a new global user ID. - * @returns {string} The new user ID which the user doc can be stored under. - */ -export function generateGlobalUserID(id?: any) { - return `${DocumentType.USER}${SEPARATOR}${id || newid()}` -} - -/** - * Gets parameters for retrieving users. - */ -export function getGlobalUserParams(globalId: any, otherProps: any = {}) { - if (!globalId) { - globalId = "" - } - const startkey = otherProps?.startkey - return { - ...otherProps, - // need to include this incase pagination - startkey: startkey - ? startkey - : `${DocumentType.USER}${SEPARATOR}${globalId}`, - endkey: `${DocumentType.USER}${SEPARATOR}${globalId}${UNICODE_MAX}`, - } -} - -/** - * Gets parameters for retrieving users, this is a utility function for the getDocParams function. - */ -export function getUserMetadataParams(userId?: string | null, otherProps = {}) { - return getRowParams(InternalTable.USER_METADATA, userId, otherProps) -} - -/** - * Generates a new user ID based on the passed in global ID. - * @param {string} globalId The ID of the global user. - * @returns {string} The new user ID which the user doc can be stored under. - */ -export function generateUserMetadataID(globalId: string) { - return generateRowID(InternalTable.USER_METADATA, globalId) -} - -/** - * Breaks up the ID to get the global ID. - */ -export function getGlobalIDFromUserMetadataID(id: string) { - const prefix = `${DocumentType.ROW}${SEPARATOR}${InternalTable.USER_METADATA}${SEPARATOR}` - if (!id || !id.includes(prefix)) { - return id - } - return id.split(prefix)[1] -} - -export function getUsersByAppParams(appId: any, otherProps: any = {}) { - const prodAppId = getProdAppID(appId) - return { - ...otherProps, - startkey: prodAppId, - endkey: `${prodAppId}${UNICODE_MAX}`, - } -} - -/** - * Generates a template ID. - * @param ownerId The owner/user of the template, this could be global or a workspace level. - */ -export function generateTemplateID(ownerId: any) { - return `${DocumentType.TEMPLATE}${SEPARATOR}${ownerId}${SEPARATOR}${newid()}` -} - -export function generateAppUserID(prodAppId: string, userId: string) { - return `${prodAppId}${SEPARATOR}${userId}` -} - -/** - * Gets parameters for retrieving templates. Owner ID must be specified, either global or a workspace level. - */ -export function getTemplateParams( - ownerId: any, - templateId: any, - otherProps = {} -) { - if (!templateId) { - templateId = "" - } - let final - if (templateId) { - final = templateId - } else { - final = `${DocumentType.TEMPLATE}${SEPARATOR}${ownerId}${SEPARATOR}` - } - return { - ...otherProps, - startkey: final, - endkey: `${final}${UNICODE_MAX}`, - } -} - -/** - * Generates a new role ID. - * @returns {string} The new role ID which the role doc can be stored under. - */ -export function generateRoleID(id?: any) { - return `${DocumentType.ROLE}${SEPARATOR}${id || newid()}` -} - -/** - * Gets parameters for retrieving a role, this is a utility function for the getDocParams function. - */ -export function getRoleParams(roleId?: string | null, otherProps = {}) { - return getDocParams(DocumentType.ROLE, roleId, otherProps) -} - -export function getStartEndKeyURL(baseKey: any, tenantId?: string) { - const tenancy = tenantId ? `${SEPARATOR}${tenantId}` : "" - return `startkey="${baseKey}${tenancy}"&endkey="${baseKey}${tenancy}${UNICODE_MAX}"` -} +import { getStartEndKeyURL } from "../docIds" +export * from "../docIds" /** * if in production this will use the CouchDB _all_dbs call to retrieve a list of databases. If testing @@ -411,29 +166,6 @@ export async function dbExists(dbName: any) { ) } -/** - * Generates a new dev info document ID - this is scoped to a user. - * @returns {string} The new dev info ID which info for dev (like api key) can be stored under. - */ -export const generateDevInfoID = (userId: any) => { - return `${DocumentType.DEV_INFO}${SEPARATOR}${userId}` -} - -/** - * Generates a new plugin ID - to be used in the global DB. - * @returns {string} The new plugin ID which a plugin metadata document can be stored under. - */ -export const generatePluginID = (name: string) => { - return `${DocumentType.PLUGIN}${SEPARATOR}${name}` -} - -/** - * Gets parameters for retrieving automations, this is a utility function for the getDocParams function. - */ -export const getPluginParams = (pluginId?: string | null, otherProps = {}) => { - return getDocParams(DocumentType.PLUGIN, pluginId, otherProps) -} - export function pagination( data: T[], pageSize: number, diff --git a/packages/backend-core/src/db/conversions.ts b/packages/backend-core/src/docIds/conversions.ts similarity index 100% rename from packages/backend-core/src/db/conversions.ts rename to packages/backend-core/src/docIds/conversions.ts diff --git a/packages/backend-core/src/docIds/ids.ts b/packages/backend-core/src/docIds/ids.ts new file mode 100644 index 0000000000..152977b3af --- /dev/null +++ b/packages/backend-core/src/docIds/ids.ts @@ -0,0 +1,102 @@ +import { + APP_PREFIX, + DocumentType, + InternalTable, + SEPARATOR, +} from "../constants" +import { newid } from "./newid" + +/** + * Generates a new app ID. + * @returns {string} The new app ID which the app doc can be stored under. + */ +export const generateAppID = (tenantId?: string | null) => { + let id = APP_PREFIX + if (tenantId) { + id += `${tenantId}${SEPARATOR}` + } + return `${id}${newid()}` +} + +/** + * Gets a new row ID for the specified table. + * @param {string} tableId The table which the row is being created for. + * @param {string|null} id If an ID is to be used then the UUID can be substituted for this. + * @returns {string} The new ID which a row doc can be stored under. + */ +export function generateRowID(tableId: string, id?: string) { + id = id || newid() + return `${DocumentType.ROW}${SEPARATOR}${tableId}${SEPARATOR}${id}` +} + +/** + * Generates a new workspace ID. + * @returns {string} The new workspace ID which the workspace doc can be stored under. + */ +export function generateWorkspaceID() { + return `${DocumentType.WORKSPACE}${SEPARATOR}${newid()}` +} + +/** + * Generates a new global user ID. + * @returns {string} The new user ID which the user doc can be stored under. + */ +export function generateGlobalUserID(id?: any) { + return `${DocumentType.USER}${SEPARATOR}${id || newid()}` +} + +/** + * Generates a new user ID based on the passed in global ID. + * @param {string} globalId The ID of the global user. + * @returns {string} The new user ID which the user doc can be stored under. + */ +export function generateUserMetadataID(globalId: string) { + return generateRowID(InternalTable.USER_METADATA, globalId) +} + +/** + * Breaks up the ID to get the global ID. + */ +export function getGlobalIDFromUserMetadataID(id: string) { + const prefix = `${DocumentType.ROW}${SEPARATOR}${InternalTable.USER_METADATA}${SEPARATOR}` + if (!id || !id.includes(prefix)) { + return id + } + return id.split(prefix)[1] +} + +/** + * Generates a template ID. + * @param ownerId The owner/user of the template, this could be global or a workspace level. + */ +export function generateTemplateID(ownerId: any) { + return `${DocumentType.TEMPLATE}${SEPARATOR}${ownerId}${SEPARATOR}${newid()}` +} + +export function generateAppUserID(prodAppId: string, userId: string) { + return `${prodAppId}${SEPARATOR}${userId}` +} + +/** + * Generates a new role ID. + * @returns {string} The new role ID which the role doc can be stored under. + */ +export function generateRoleID(id?: any) { + return `${DocumentType.ROLE}${SEPARATOR}${id || newid()}` +} + +/** + * Generates a new dev info document ID - this is scoped to a user. + * @returns {string} The new dev info ID which info for dev (like api key) can be stored under. + */ +export const generateDevInfoID = (userId: any) => { + return `${DocumentType.DEV_INFO}${SEPARATOR}${userId}` +} + +/** + * Generates a new plugin ID - to be used in the global DB. + * @returns {string} The new plugin ID which a plugin metadata document can be stored under. + */ +export const generatePluginID = (name: string) => { + return `${DocumentType.PLUGIN}${SEPARATOR}${name}` +} diff --git a/packages/backend-core/src/docIds/index.ts b/packages/backend-core/src/docIds/index.ts new file mode 100644 index 0000000000..1d22b375be --- /dev/null +++ b/packages/backend-core/src/docIds/index.ts @@ -0,0 +1,2 @@ +export * from "./ids" +export * from "./params" diff --git a/packages/backend-core/src/newid.ts b/packages/backend-core/src/docIds/newid.ts similarity index 100% rename from packages/backend-core/src/newid.ts rename to packages/backend-core/src/docIds/newid.ts diff --git a/packages/backend-core/src/docIds/params.ts b/packages/backend-core/src/docIds/params.ts new file mode 100644 index 0000000000..5d563952f7 --- /dev/null +++ b/packages/backend-core/src/docIds/params.ts @@ -0,0 +1,174 @@ +import { + DocumentType, + InternalTable, + SEPARATOR, + UNICODE_MAX, + ViewName, +} from "../constants" +import { getProdAppID } from "./conversions" + +/** + * If creating DB allDocs/query params with only a single top level ID this can be used, this + * is usually the case as most of our docs are top level e.g. tables, automations, users and so on. + * More complex cases such as link docs and rows which have multiple levels of IDs that their + * ID consists of need their own functions to build the allDocs parameters. + * @param {string} docType The type of document which input params are being built for, e.g. user, + * link, app, table and so on. + * @param {string|null} docId The ID of the document minus its type - this is only needed if looking + * for a singular document. + * @param {object} otherProps Add any other properties onto the request, e.g. include_docs. + * @returns {object} Parameters which can then be used with an allDocs request. + */ +export function getDocParams( + docType: string, + docId?: string | null, + otherProps: any = {} +) { + if (docId == null) { + docId = "" + } + return { + ...otherProps, + startkey: `${docType}${SEPARATOR}${docId}`, + endkey: `${docType}${SEPARATOR}${docId}${UNICODE_MAX}`, + } +} + +/** + * Gets the DB allDocs/query params for retrieving a row. + * @param {string|null} tableId The table in which the rows have been stored. + * @param {string|null} rowId The ID of the row which is being specifically queried for. This can be + * left null to get all the rows in the table. + * @param {object} otherProps Any other properties to add to the request. + * @returns {object} Parameters which can then be used with an allDocs request. + */ +export function getRowParams( + tableId?: string | null, + rowId?: string | null, + otherProps = {} +) { + if (tableId == null) { + return getDocParams(DocumentType.ROW, null, otherProps) + } + + const endOfKey = rowId == null ? `${tableId}${SEPARATOR}` : rowId + + return getDocParams(DocumentType.ROW, endOfKey, otherProps) +} + +/** + * Retrieve the correct index for a view based on default design DB. + */ +export function getQueryIndex(viewName: ViewName) { + return `database/${viewName}` +} + +/** + * Check if a given ID is that of a table. + * @returns {boolean} + */ +export const isTableId = (id: string) => { + // this includes datasource plus tables + return ( + id && + (id.startsWith(`${DocumentType.TABLE}${SEPARATOR}`) || + id.startsWith(`${DocumentType.DATASOURCE_PLUS}${SEPARATOR}`)) + ) +} + +/** + * Check if a given ID is that of a datasource or datasource plus. + * @returns {boolean} + */ +export const isDatasourceId = (id: string) => { + // this covers both datasources and datasource plus + return id && id.startsWith(`${DocumentType.DATASOURCE}${SEPARATOR}`) +} + +/** + * Gets parameters for retrieving workspaces. + */ +export function getWorkspaceParams(id = "", otherProps = {}) { + return { + ...otherProps, + startkey: `${DocumentType.WORKSPACE}${SEPARATOR}${id}`, + endkey: `${DocumentType.WORKSPACE}${SEPARATOR}${id}${UNICODE_MAX}`, + } +} + +/** + * Gets parameters for retrieving users. + */ +export function getGlobalUserParams(globalId: any, otherProps: any = {}) { + if (!globalId) { + globalId = "" + } + const startkey = otherProps?.startkey + return { + ...otherProps, + // need to include this incase pagination + startkey: startkey + ? startkey + : `${DocumentType.USER}${SEPARATOR}${globalId}`, + endkey: `${DocumentType.USER}${SEPARATOR}${globalId}${UNICODE_MAX}`, + } +} + +/** + * Gets parameters for retrieving users, this is a utility function for the getDocParams function. + */ +export function getUserMetadataParams(userId?: string | null, otherProps = {}) { + return getRowParams(InternalTable.USER_METADATA, userId, otherProps) +} + +export function getUsersByAppParams(appId: any, otherProps: any = {}) { + const prodAppId = getProdAppID(appId) + return { + ...otherProps, + startkey: prodAppId, + endkey: `${prodAppId}${UNICODE_MAX}`, + } +} + +/** + * Gets parameters for retrieving templates. Owner ID must be specified, either global or a workspace level. + */ +export function getTemplateParams( + ownerId: any, + templateId: any, + otherProps = {} +) { + if (!templateId) { + templateId = "" + } + let final + if (templateId) { + final = templateId + } else { + final = `${DocumentType.TEMPLATE}${SEPARATOR}${ownerId}${SEPARATOR}` + } + return { + ...otherProps, + startkey: final, + endkey: `${final}${UNICODE_MAX}`, + } +} + +/** + * Gets parameters for retrieving a role, this is a utility function for the getDocParams function. + */ +export function getRoleParams(roleId?: string | null, otherProps = {}) { + return getDocParams(DocumentType.ROLE, roleId, otherProps) +} + +export function getStartEndKeyURL(baseKey: any, tenantId?: string) { + const tenancy = tenantId ? `${SEPARATOR}${tenantId}` : "" + return `startkey="${baseKey}${tenancy}"&endkey="${baseKey}${tenancy}${UNICODE_MAX}"` +} + +/** + * Gets parameters for retrieving automations, this is a utility function for the getDocParams function. + */ +export const getPluginParams = (pluginId?: string | null, otherProps = {}) => { + return getDocParams(DocumentType.PLUGIN, pluginId, otherProps) +} diff --git a/packages/backend-core/src/errors/errors.ts b/packages/backend-core/src/errors/errors.ts index 54ca8456ab..4e1f1abbb5 100644 --- a/packages/backend-core/src/errors/errors.ts +++ b/packages/backend-core/src/errors/errors.ts @@ -97,3 +97,11 @@ export class InvalidAPIKeyError extends BudibaseError { ) } } + +// USERS + +export class EmailUnavailableError extends Error { + constructor(email: string) { + super(`Email already in use: '${email}'`) + } +} diff --git a/packages/backend-core/src/events/processors/posthog/tests/PosthogProcessor.spec.ts b/packages/backend-core/src/events/processors/posthog/tests/PosthogProcessor.spec.ts index 8df4e40bcf..0722fc3293 100644 --- a/packages/backend-core/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +++ b/packages/backend-core/src/events/processors/posthog/tests/PosthogProcessor.spec.ts @@ -1,4 +1,4 @@ -import { testEnv } from "../../../../../tests" +import { testEnv } from "../../../../../tests/extra" import PosthogProcessor from "../PosthogProcessor" import { Event, IdentityType, Hosting } from "@budibase/types" const tk = require("timekeeper") diff --git a/packages/backend-core/src/middleware/passport/sso/tests/sso.spec.ts b/packages/backend-core/src/middleware/passport/sso/tests/sso.spec.ts index ae42fc01ea..484a118cbd 100644 --- a/packages/backend-core/src/middleware/passport/sso/tests/sso.spec.ts +++ b/packages/backend-core/src/middleware/passport/sso/tests/sso.spec.ts @@ -1,4 +1,5 @@ -import { structures, testEnv, mocks } from "../../../../../tests" +import { structures, mocks } from "../../../../../tests" +import { testEnv } from "../../../../../tests/extra" import { SSOAuthDetails, User } from "@budibase/types" import { HTTPError } from "../../../../errors" diff --git a/packages/backend-core/src/migrations/tests/__snapshots__/migrations.spec.ts.snap b/packages/backend-core/src/migrations/tests/__snapshots__/migrations.spec.ts.snap index 5129869232..377900b5d5 100644 --- a/packages/backend-core/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +++ b/packages/backend-core/src/migrations/tests/__snapshots__/migrations.spec.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`migrations should match snapshot 1`] = ` -Object { +{ "_id": "migrations", "_rev": "1-2f64479842a0513aa8b97f356b0b9127", "createdAt": "2020-01-01T00:00:00.000Z", diff --git a/packages/backend-core/src/migrations/tests/migrations.spec.ts b/packages/backend-core/src/migrations/tests/migrations.spec.ts index c74ab816c1..af2eb33cf5 100644 --- a/packages/backend-core/src/migrations/tests/migrations.spec.ts +++ b/packages/backend-core/src/migrations/tests/migrations.spec.ts @@ -1,4 +1,4 @@ -import { testEnv, DBTestConfiguration } from "../../../tests" +import { testEnv, DBTestConfiguration } from "../../../tests/extra" import * as migrations from "../index" import * as context from "../../context" import { MigrationType } from "@budibase/types" diff --git a/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts b/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts index 0375e97cbc..aaa07ec9d3 100644 --- a/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts +++ b/packages/backend-core/src/objectStore/buckets/tests/app.spec.ts @@ -1,6 +1,6 @@ import * as app from "../app" import { getAppFileUrl } from "../app" -import { testEnv } from "../../../../tests" +import { testEnv } from "../../../../tests/extra" describe("app", () => { beforeEach(() => { diff --git a/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts b/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts index b495812356..148a4c80bf 100644 --- a/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts +++ b/packages/backend-core/src/objectStore/buckets/tests/global.spec.ts @@ -1,5 +1,5 @@ import * as global from "../global" -import { testEnv } from "../../../../tests" +import { testEnv } from "../../../../tests/extra" describe("global", () => { describe("getGlobalFileUrl", () => { diff --git a/packages/backend-core/src/objectStore/buckets/tests/plugins.spec.ts b/packages/backend-core/src/objectStore/buckets/tests/plugins.spec.ts index affb8d8318..fc2822314e 100644 --- a/packages/backend-core/src/objectStore/buckets/tests/plugins.spec.ts +++ b/packages/backend-core/src/objectStore/buckets/tests/plugins.spec.ts @@ -1,5 +1,6 @@ import * as plugins from "../plugins" -import { structures, testEnv } from "../../../../tests" +import { structures } from "../../../../tests" +import { testEnv } from "../../../../tests/extra" describe("plugins", () => { describe("enrichPluginURLs", () => { diff --git a/packages/backend-core/src/platform/tests/tenants.spec.ts b/packages/backend-core/src/platform/tests/tenants.spec.ts index 92e999cb2d..b2ab75c954 100644 --- a/packages/backend-core/src/platform/tests/tenants.spec.ts +++ b/packages/backend-core/src/platform/tests/tenants.spec.ts @@ -1,4 +1,5 @@ -import { DBTestConfiguration, structures } from "../../../tests" +import { structures } from "../../../tests" +import { DBTestConfiguration } from "../../../tests/extra" import * as tenants from "../tenants" describe("tenants", () => { diff --git a/packages/backend-core/src/security/encryption.ts b/packages/backend-core/src/security/encryption.ts index d2c8f18f73..f9adb68955 100644 --- a/packages/backend-core/src/security/encryption.ts +++ b/packages/backend-core/src/security/encryption.ts @@ -12,7 +12,7 @@ export enum SecretOption { ENCRYPTION = "encryption", } -function getSecret(secretOption: SecretOption): string { +export function getSecret(secretOption: SecretOption): string { let secret, secretName switch (secretOption) { case SecretOption.ENCRYPTION: diff --git a/packages/backend-core/src/security/tests/encryption.spec.ts b/packages/backend-core/src/security/tests/encryption.spec.ts new file mode 100644 index 0000000000..0b7eb96b68 --- /dev/null +++ b/packages/backend-core/src/security/tests/encryption.spec.ts @@ -0,0 +1,31 @@ +import { encrypt, decrypt, SecretOption, getSecret } from "../encryption" +import env from "../../environment" + +describe("encryption", () => { + it("should throw an error if API encryption key is not set", () => { + const jwt = getSecret(SecretOption.API) + expect(jwt).toBe(env.JWT_SECRET) + }) + + it("should throw an error if encryption key is not set", () => { + expect(() => getSecret(SecretOption.ENCRYPTION)).toThrow( + 'Secret "ENCRYPTION_KEY" has not been set in environment.' + ) + }) + + it("should encrypt and decrypt a string using API encryption key", () => { + env._set("API_ENCRYPTION_KEY", "api_secret") + const plaintext = "budibase" + const apiEncrypted = encrypt(plaintext, SecretOption.API) + const decrypted = decrypt(apiEncrypted, SecretOption.API) + expect(decrypted).toEqual(plaintext) + }) + + it("should encrypt and decrypt a string using encryption key", () => { + env._set("ENCRYPTION_KEY", "normal_secret") + const plaintext = "budibase" + const encryptionEncrypted = encrypt(plaintext, SecretOption.ENCRYPTION) + const decrypted = decrypt(encryptionEncrypted, SecretOption.ENCRYPTION) + expect(decrypted).toEqual(plaintext) + }) +}) diff --git a/packages/backend-core/src/tenancy/tenancy.ts b/packages/backend-core/src/tenancy/tenancy.ts index e8ddf88226..7b17bdbe18 100644 --- a/packages/backend-core/src/tenancy/tenancy.ts +++ b/packages/backend-core/src/tenancy/tenancy.ts @@ -3,8 +3,8 @@ import { getTenantId, getTenantIDFromAppID, isMultiTenant, + getPlatformURL, } from "../context" -import env from "../environment" import { BBContext, TenantResolutionStrategy, @@ -93,7 +93,7 @@ export const getTenantIDFromCtx = ( // subdomain if (isAllowed(TenantResolutionStrategy.SUBDOMAIN)) { // e.g. budibase.app or local.com:10000 - const platformHost = new URL(env.PLATFORM_URL).host.split(":")[0] + const platformHost = new URL(getPlatformURL()).host.split(":")[0] // e.g. tenant.budibase.app or tenant.local.com const requestHost = ctx.host // parse the tenant id from the difference diff --git a/packages/backend-core/src/tenancy/tests/tenancy.spec.ts b/packages/backend-core/src/tenancy/tests/tenancy.spec.ts new file mode 100644 index 0000000000..ebeaca074c --- /dev/null +++ b/packages/backend-core/src/tenancy/tests/tenancy.spec.ts @@ -0,0 +1,184 @@ +import { TenantResolutionStrategy } from "@budibase/types" +import { addTenantToUrl, isUserInAppTenant, getTenantIDFromCtx } from "../" +import { isMultiTenant, getTenantIDFromAppID } from "../../context" + +jest.mock("../../context", () => ({ + getTenantId: jest.fn(() => "budibase"), + isMultiTenant: jest.fn(() => true), + getTenantIDFromAppID: jest.fn(), + getPlatformURL: jest.fn(() => "https://app.com"), + DEFAULT_TENANT_ID: "default", +})) + +const mockedIsMultiTenant = isMultiTenant as jest.MockedFunction< + typeof isMultiTenant +> +const mockedGetTenantIDFromAppID = getTenantIDFromAppID as jest.MockedFunction< + typeof getTenantIDFromAppID +> + +describe("addTenantToUrl", () => { + it("should append tenantId parameter to the URL", () => { + const url = "https://budibase.com" + const expectedUrl = "https://budibase.com?tenantId=budibase" + expect(addTenantToUrl(url)).toEqual(expectedUrl) + }) + + it("should append tenantId parameter to the URL query string", () => { + const url = "https://budibase.com?var=test" + const expectedUrl = "https://budibase.com?var=test&tenantId=budibase" + expect(addTenantToUrl(url)).toEqual(expectedUrl) + }) + + it("should not append tenantId parameter to the URL if isMultiTenant is false", () => { + mockedIsMultiTenant.mockImplementation(() => false) + + const url = "https://budibase.com" + const expectedUrl = "https://budibase.com" + expect(addTenantToUrl(url)).toEqual(expectedUrl) + }) +}) + +describe("isUserInAppTenant", () => { + mockedGetTenantIDFromAppID.mockImplementation(() => "budibase") + const mockUser = { tenantId: "budibase" } + + it("returns true if user tenant ID matches app tenant ID", () => { + const appId = "app-budibase" + const result = isUserInAppTenant(appId, mockUser) + expect(result).toBe(true) + }) + + it("uses default tenant ID if user is not provided", () => { + const appId = "app-budibase" + const result = isUserInAppTenant(appId) + expect(result).toBe(true) + }) + + it("uses default tenant ID if app tenant ID is not found", () => { + const appId = "not-budibase-app" + const result = isUserInAppTenant(appId, mockUser) + expect(result).toBe(true) + }) + + it("returns false if user tenant ID does not match app tenant ID", () => { + const appId = "app-budibase" + mockedGetTenantIDFromAppID.mockImplementation(() => "not-budibase") + const result = isUserInAppTenant(appId, mockUser) + expect(result).toBe(false) + }) +}) + +let mockOpts: any = {} +function createCtx(opts: { + originalUrl?: string + headers?: Record + qsTenantId?: string + userTenantId?: string + host?: string + path?: string +}) { + const createdCtx: any = { + originalUrl: opts.originalUrl || "budibase.com", + matched: [{ name: "name" }], + throw: jest.fn(), + request: { headers: {} }, + } + if (opts.headers) { + createdCtx.request.headers = opts.headers + } + if (opts.qsTenantId) { + createdCtx.request.query = { tenantId: opts.qsTenantId } + } + if (opts.userTenantId) { + createdCtx.user = { tenantId: opts.userTenantId } + } + if (opts.host) { + createdCtx.host = opts.host + } + if (opts.path) { + createdCtx.matched = [ + { + paramNames: [{ name: "tenantId" }], + params: () => ({ tenantId: opts.path }), + captures: jest.fn(), + }, + ] + } + + return createdCtx as any +} + +describe("getTenantIDFromCtx", () => { + describe("when tenant can be found", () => { + it("returns the tenant ID from the user object", () => { + mockedIsMultiTenant.mockImplementation(() => true) + const ctx = createCtx({ userTenantId: "budibase" }) + expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("budibase") + }) + + it("returns the tenant ID from the header", () => { + mockedIsMultiTenant.mockImplementation(() => true) + const ctx = createCtx({ headers: { "x-budibase-tenant-id": "budibase" } }) + mockOpts = { includeStrategies: [TenantResolutionStrategy.HEADER] } + expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("budibase") + }) + + it("returns the tenant ID from the query param", () => { + mockedIsMultiTenant.mockImplementation(() => true) + mockOpts = { includeStrategies: [TenantResolutionStrategy.QUERY] } + const ctx = createCtx({ qsTenantId: "budibase" }) + expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("budibase") + }) + + it("returns the tenant ID from the subdomain", () => { + mockedIsMultiTenant.mockImplementation(() => true) + const ctx = createCtx({ host: "bb.app.com" }) + mockOpts = { includeStrategies: [TenantResolutionStrategy.SUBDOMAIN] } + expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("bb") + }) + + it("returns the tenant ID from the path", () => { + mockedIsMultiTenant.mockImplementation(() => true) + const ctx = createCtx({ path: "bb" }) + mockOpts = { includeStrategies: [TenantResolutionStrategy.PATH] } + expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("bb") + }) + }) + + describe("when tenant cannot be found", () => { + it("throws a 403 error if allowNoTenant is false", () => { + const ctx = createCtx({}) + mockOpts = { + allowNoTenant: false, + excludeStrategies: [ + TenantResolutionStrategy.QUERY, + TenantResolutionStrategy.SUBDOMAIN, + TenantResolutionStrategy.PATH, + ], + } + expect(getTenantIDFromCtx(ctx, mockOpts)).toBeNull() + expect(ctx.throw).toBeCalledTimes(1) + expect(ctx.throw).toBeCalledWith(403, "Tenant id not set") + }) + + it("returns null if allowNoTenant is true", () => { + const ctx = createCtx({}) + mockOpts = { + allowNoTenant: true, + excludeStrategies: [ + TenantResolutionStrategy.QUERY, + TenantResolutionStrategy.SUBDOMAIN, + TenantResolutionStrategy.PATH, + ], + } + expect(getTenantIDFromCtx(ctx, mockOpts)).toBeNull() + }) + }) + + it("returns the default tenant ID when isMultiTenant() returns false", () => { + mockedIsMultiTenant.mockImplementation(() => false) + const ctx = createCtx({}) + expect(getTenantIDFromCtx(ctx, mockOpts)).toEqual("default") + }) +}) diff --git a/packages/backend-core/src/utils/hashing.ts b/packages/backend-core/src/utils/hashing.ts index 220ffea47f..aba11f38e6 100644 --- a/packages/backend-core/src/utils/hashing.ts +++ b/packages/backend-core/src/utils/hashing.ts @@ -1,5 +1,5 @@ import env from "../environment" -export * from "../newid" +export * from "../docIds/newid" const bcrypt = env.JS_BCRYPT ? require("bcryptjs") : require("bcrypt") const SALT_ROUNDS = env.SALT_ROUNDS || 10 diff --git a/packages/backend-core/src/utils/tests/utils.spec.ts b/packages/backend-core/src/utils/tests/utils.spec.ts index 7d6c5561e8..ededa48628 100644 --- a/packages/backend-core/src/utils/tests/utils.spec.ts +++ b/packages/backend-core/src/utils/tests/utils.spec.ts @@ -1,4 +1,5 @@ -import { structures, DBTestConfiguration } from "../../../tests" +import { structures } from "../../../tests" +import { DBTestConfiguration } from "../../../tests/extra" import * as utils from "../../utils" import * as db from "../../db" import { Header } from "../../constants" diff --git a/packages/backend-core/tests/core/logging.ts b/packages/backend-core/tests/core/logging.ts new file mode 100644 index 0000000000..271f4d62ff --- /dev/null +++ b/packages/backend-core/tests/core/logging.ts @@ -0,0 +1,34 @@ +export enum LogLevel { + TRACE = "trace", + DEBUG = "debug", + INFO = "info", + WARN = "warn", + ERROR = "error", +} + +const LOG_INDEX: { [key in LogLevel]: number } = { + [LogLevel.TRACE]: 1, + [LogLevel.DEBUG]: 2, + [LogLevel.INFO]: 3, + [LogLevel.WARN]: 4, + [LogLevel.ERROR]: 5, +} + +const setIndex = LOG_INDEX[process.env.LOG_LEVEL as LogLevel] + +if (setIndex > LOG_INDEX.trace) { + global.console.trace = jest.fn() +} + +if (setIndex > LOG_INDEX.debug) { + global.console.debug = jest.fn() +} + +if (setIndex > LOG_INDEX.info) { + global.console.info = jest.fn() + global.console.log = jest.fn() +} + +if (setIndex > LOG_INDEX.warn) { + global.console.warn = jest.fn() +} diff --git a/packages/backend-core/tests/utilities/index.ts b/packages/backend-core/tests/core/utilities/index.ts similarity index 65% rename from packages/backend-core/tests/utilities/index.ts rename to packages/backend-core/tests/core/utilities/index.ts index 1c73216d76..eee41cc3d4 100644 --- a/packages/backend-core/tests/utilities/index.ts +++ b/packages/backend-core/tests/core/utilities/index.ts @@ -1,9 +1,6 @@ export * as mocks from "./mocks" export * as structures from "./structures" export { generator } from "./structures" -export * as testEnv from "./testEnv" export * as testContainerUtils from "./testContainerUtils" export * from "./jestUtils" - -export { default as DBTestConfiguration } from "./DBTestConfiguration" diff --git a/packages/backend-core/tests/utilities/jestUtils.ts b/packages/backend-core/tests/core/utilities/jestUtils.ts similarity index 100% rename from packages/backend-core/tests/utilities/jestUtils.ts rename to packages/backend-core/tests/core/utilities/jestUtils.ts diff --git a/packages/backend-core/tests/core/utilities/mocks/alerts.ts b/packages/backend-core/tests/core/utilities/mocks/alerts.ts new file mode 100644 index 0000000000..90c9759c92 --- /dev/null +++ b/packages/backend-core/tests/core/utilities/mocks/alerts.ts @@ -0,0 +1,3 @@ +jest.mock("../../../../src/logging/alerts") +import * as _alerts from "../../../../src/logging/alerts" +export const alerts = jest.mocked(_alerts) diff --git a/packages/backend-core/tests/utilities/mocks/date.ts b/packages/backend-core/tests/core/utilities/mocks/date.ts similarity index 100% rename from packages/backend-core/tests/utilities/mocks/date.ts rename to packages/backend-core/tests/core/utilities/mocks/date.ts diff --git a/packages/backend-core/tests/core/utilities/mocks/events.ts b/packages/backend-core/tests/core/utilities/mocks/events.ts new file mode 100644 index 0000000000..17e35a5d0c --- /dev/null +++ b/packages/backend-core/tests/core/utilities/mocks/events.ts @@ -0,0 +1,123 @@ +beforeAll(async () => { + const processors = await import("../../../../src/events/processors") + const events = await import("../../../../src/events") + jest.spyOn(processors.analyticsProcessor, "processEvent") + + jest.spyOn(events.identification, "identifyTenantGroup") + jest.spyOn(events.identification, "identifyUser") + + jest.spyOn(events.backfill, "appSucceeded") + jest.spyOn(events.backfill, "tenantSucceeded") + + jest.spyOn(events.account, "created") + jest.spyOn(events.account, "deleted") + jest.spyOn(events.account, "verified") + + jest.spyOn(events.app, "created") + jest.spyOn(events.app, "updated") + jest.spyOn(events.app, "deleted") + jest.spyOn(events.app, "published") + jest.spyOn(events.app, "unpublished") + jest.spyOn(events.app, "templateImported") + jest.spyOn(events.app, "fileImported") + jest.spyOn(events.app, "versionUpdated") + jest.spyOn(events.app, "versionReverted") + jest.spyOn(events.app, "reverted") + jest.spyOn(events.app, "exported") + + jest.spyOn(events.auth, "login") + jest.spyOn(events.auth, "logout") + jest.spyOn(events.auth, "SSOCreated") + jest.spyOn(events.auth, "SSOUpdated") + jest.spyOn(events.auth, "SSOActivated") + jest.spyOn(events.auth, "SSODeactivated") + + jest.spyOn(events.automation, "created") + jest.spyOn(events.automation, "deleted") + jest.spyOn(events.automation, "tested") + jest.spyOn(events.automation, "stepCreated") + jest.spyOn(events.automation, "stepDeleted") + jest.spyOn(events.automation, "triggerUpdated") + + jest.spyOn(events.datasource, "created") + jest.spyOn(events.datasource, "updated") + jest.spyOn(events.datasource, "deleted") + + jest.spyOn(events.email, "SMTPCreated") + jest.spyOn(events.email, "SMTPUpdated") + + jest.spyOn(events.layout, "created") + jest.spyOn(events.layout, "deleted") + + jest.spyOn(events.org, "nameUpdated") + jest.spyOn(events.org, "logoUpdated") + jest.spyOn(events.org, "platformURLUpdated") + jest.spyOn(events.org, "analyticsOptOut") + + jest.spyOn(events.installation, "versionChecked") + + jest.spyOn(events.query, "created") + jest.spyOn(events.query, "updated") + jest.spyOn(events.query, "deleted") + jest.spyOn(events.query, "imported") + jest.spyOn(events.query, "previewed") + + jest.spyOn(events.role, "created") + jest.spyOn(events.role, "updated") + jest.spyOn(events.role, "deleted") + jest.spyOn(events.role, "assigned") + jest.spyOn(events.role, "unassigned") + + jest.spyOn(events.rows, "imported") + jest.spyOn(events.rows, "created") + + jest.spyOn(events.screen, "created") + jest.spyOn(events.screen, "deleted") + + jest.spyOn(events.user, "created") + jest.spyOn(events.user, "updated") + jest.spyOn(events.user, "deleted") + jest.spyOn(events.user, "permissionAdminAssigned") + jest.spyOn(events.user, "permissionAdminRemoved") + jest.spyOn(events.user, "permissionBuilderAssigned") + jest.spyOn(events.user, "permissionBuilderRemoved") + jest.spyOn(events.user, "invited") + jest.spyOn(events.user, "inviteAccepted") + jest.spyOn(events.user, "passwordForceReset") + jest.spyOn(events.user, "passwordUpdated") + jest.spyOn(events.user, "passwordResetRequested") + jest.spyOn(events.user, "passwordReset") + + jest.spyOn(events.group, "created") + jest.spyOn(events.group, "updated") + jest.spyOn(events.group, "deleted") + jest.spyOn(events.group, "usersAdded") + jest.spyOn(events.group, "usersDeleted") + jest.spyOn(events.group, "createdOnboarding") + jest.spyOn(events.group, "permissionsEdited") + + jest.spyOn(events.serve, "servedBuilder") + jest.spyOn(events.serve, "servedApp") + jest.spyOn(events.serve, "servedAppPreview") + + jest.spyOn(events.table, "created") + jest.spyOn(events.table, "updated") + jest.spyOn(events.table, "deleted") + jest.spyOn(events.table, "exported") + jest.spyOn(events.table, "imported") + + jest.spyOn(events.view, "created") + jest.spyOn(events.view, "updated") + jest.spyOn(events.view, "deleted") + jest.spyOn(events.view, "exported") + jest.spyOn(events.view, "filterCreated") + jest.spyOn(events.view, "filterUpdated") + jest.spyOn(events.view, "filterDeleted") + jest.spyOn(events.view, "calculationCreated") + jest.spyOn(events.view, "calculationUpdated") + jest.spyOn(events.view, "calculationDeleted") + + jest.spyOn(events.plugin, "init") + jest.spyOn(events.plugin, "imported") + jest.spyOn(events.plugin, "deleted") +}) diff --git a/packages/backend-core/tests/core/utilities/mocks/fetch.ts b/packages/backend-core/tests/core/utilities/mocks/fetch.ts new file mode 100644 index 0000000000..287280067a --- /dev/null +++ b/packages/backend-core/tests/core/utilities/mocks/fetch.ts @@ -0,0 +1,17 @@ +const mockFetch = jest.fn((url: any, opts: any) => { + const fetch = jest.requireActual("node-fetch") + const env = jest.requireActual("../../../../src/environment").default + if (url.includes(env.COUCH_DB_URL)) { + return fetch(url, opts) + } + return undefined +}) + +const enable = () => { + jest.mock("node-fetch", () => mockFetch) +} + +export default { + ...mockFetch, + enable, +} diff --git a/packages/backend-core/tests/utilities/mocks/index.ts b/packages/backend-core/tests/core/utilities/mocks/index.ts similarity index 70% rename from packages/backend-core/tests/utilities/mocks/index.ts rename to packages/backend-core/tests/core/utilities/mocks/index.ts index 915021cecf..9a72b38ef5 100644 --- a/packages/backend-core/tests/utilities/mocks/index.ts +++ b/packages/backend-core/tests/core/utilities/mocks/index.ts @@ -1,10 +1,10 @@ -jest.mock("../../../src/accounts") -import * as _accounts from "../../../src/accounts" +jest.mock("../../../../src/accounts") +import * as _accounts from "../../../../src/accounts" export const accounts = jest.mocked(_accounts) export * as date from "./date" export * as licenses from "./licenses" export { default as fetch } from "./fetch" export * from "./alerts" -import "./posthog" import "./events" +import "./posthog" diff --git a/packages/backend-core/tests/utilities/mocks/licenses.ts b/packages/backend-core/tests/core/utilities/mocks/licenses.ts similarity index 100% rename from packages/backend-core/tests/utilities/mocks/licenses.ts rename to packages/backend-core/tests/core/utilities/mocks/licenses.ts diff --git a/packages/backend-core/tests/utilities/mocks/posthog.ts b/packages/backend-core/tests/core/utilities/mocks/posthog.ts similarity index 100% rename from packages/backend-core/tests/utilities/mocks/posthog.ts rename to packages/backend-core/tests/core/utilities/mocks/posthog.ts diff --git a/packages/backend-core/tests/utilities/structures/accounts.ts b/packages/backend-core/tests/core/utilities/structures/accounts.ts similarity index 96% rename from packages/backend-core/tests/utilities/structures/accounts.ts rename to packages/backend-core/tests/core/utilities/structures/accounts.ts index 62a9ac19d1..30ef6e4192 100644 --- a/packages/backend-core/tests/utilities/structures/accounts.ts +++ b/packages/backend-core/tests/core/utilities/structures/accounts.ts @@ -1,5 +1,5 @@ import { generator, uuid } from "." -import * as db from "../../../src/db/utils" +import { generateGlobalUserID } from "../../../../src/docIds" import { Account, AccountSSOProvider, @@ -39,7 +39,7 @@ export const cloudAccount = (): CloudAccount => { return { ...account(), hosting: Hosting.CLOUD, - budibaseUserId: db.generateGlobalUserID(), + budibaseUserId: generateGlobalUserID(), } } diff --git a/packages/backend-core/tests/utilities/structures/apps.ts b/packages/backend-core/tests/core/utilities/structures/apps.ts similarity index 84% rename from packages/backend-core/tests/utilities/structures/apps.ts rename to packages/backend-core/tests/core/utilities/structures/apps.ts index f3743d99b2..812d6d8177 100644 --- a/packages/backend-core/tests/utilities/structures/apps.ts +++ b/packages/backend-core/tests/core/utilities/structures/apps.ts @@ -1,6 +1,6 @@ import { generator } from "." import { App } from "@budibase/types" -import { DEFAULT_TENANT_ID, DocumentType } from "../../../src/constants" +import { DEFAULT_TENANT_ID, DocumentType } from "../../../../src/constants" export function app(id: string): App { return { diff --git a/packages/backend-core/tests/utilities/structures/common.ts b/packages/backend-core/tests/core/utilities/structures/common.ts similarity index 100% rename from packages/backend-core/tests/utilities/structures/common.ts rename to packages/backend-core/tests/core/utilities/structures/common.ts diff --git a/packages/backend-core/tests/utilities/structures/db.ts b/packages/backend-core/tests/core/utilities/structures/db.ts similarity index 80% rename from packages/backend-core/tests/utilities/structures/db.ts rename to packages/backend-core/tests/core/utilities/structures/db.ts index f4a677e777..31a52dce8b 100644 --- a/packages/backend-core/tests/utilities/structures/db.ts +++ b/packages/backend-core/tests/core/utilities/structures/db.ts @@ -1,5 +1,5 @@ import { structures } from ".." -import { newid } from "../../../src/newid" +import { newid } from "../../../../src/docIds/newid" export function id() { return `db_${newid()}` diff --git a/packages/backend-core/tests/utilities/structures/generator.ts b/packages/backend-core/tests/core/utilities/structures/generator.ts similarity index 100% rename from packages/backend-core/tests/utilities/structures/generator.ts rename to packages/backend-core/tests/core/utilities/structures/generator.ts diff --git a/packages/backend-core/tests/utilities/structures/index.ts b/packages/backend-core/tests/core/utilities/structures/index.ts similarity index 100% rename from packages/backend-core/tests/utilities/structures/index.ts rename to packages/backend-core/tests/core/utilities/structures/index.ts diff --git a/packages/backend-core/tests/utilities/structures/koa.ts b/packages/backend-core/tests/core/utilities/structures/koa.ts similarity index 100% rename from packages/backend-core/tests/utilities/structures/koa.ts rename to packages/backend-core/tests/core/utilities/structures/koa.ts diff --git a/packages/backend-core/tests/utilities/structures/licenses.ts b/packages/backend-core/tests/core/utilities/structures/licenses.ts similarity index 100% rename from packages/backend-core/tests/utilities/structures/licenses.ts rename to packages/backend-core/tests/core/utilities/structures/licenses.ts diff --git a/packages/backend-core/tests/utilities/structures/plugins.ts b/packages/backend-core/tests/core/utilities/structures/plugins.ts similarity index 100% rename from packages/backend-core/tests/utilities/structures/plugins.ts rename to packages/backend-core/tests/core/utilities/structures/plugins.ts diff --git a/packages/backend-core/tests/utilities/structures/scim.ts b/packages/backend-core/tests/core/utilities/structures/scim.ts similarity index 62% rename from packages/backend-core/tests/utilities/structures/scim.ts rename to packages/backend-core/tests/core/utilities/structures/scim.ts index 6657bb90b5..741cff165e 100644 --- a/packages/backend-core/tests/utilities/structures/scim.ts +++ b/packages/backend-core/tests/core/utilities/structures/scim.ts @@ -1,23 +1,31 @@ import { ScimCreateGroupRequest, ScimCreateUserRequest } from "@budibase/types" import { uuid } from "./common" import { generator } from "./generator" +import _ from "lodash" -export function createUserRequest(userData?: { - externalId?: string - email?: string - firstName?: string - lastName?: string - username?: string -}) { - const { - externalId = uuid(), - email = generator.email(), - firstName = generator.first(), - lastName = generator.last(), - username = generator.name(), - } = userData || {} +interface CreateUserRequestFields { + externalId: string + email: string + firstName: string + lastName: string + username: string +} - const user: ScimCreateUserRequest = { +export function createUserRequest(userData?: Partial) { + const defaultValues = { + externalId: uuid(), + email: generator.email(), + firstName: generator.first(), + lastName: generator.last(), + username: generator.name(), + } + + const { externalId, email, firstName, lastName, username } = _.assign( + defaultValues, + userData + ) + + let user: ScimCreateUserRequest = { schemas: [ "urn:ietf:params:scim:schemas:core:2.0:User", "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User", @@ -35,13 +43,17 @@ export function createUserRequest(userData?: { meta: { resourceType: "User", }, - name: { - formatted: generator.name(), - familyName: lastName, - givenName: firstName, - }, roles: [], } + + if (firstName || lastName) { + user.name = { + formatted: [firstName, lastName].filter(s => s).join(" "), + familyName: lastName, + givenName: firstName, + } + } + return user } diff --git a/packages/backend-core/tests/utilities/structures/shared.ts b/packages/backend-core/tests/core/utilities/structures/shared.ts similarity index 100% rename from packages/backend-core/tests/utilities/structures/shared.ts rename to packages/backend-core/tests/core/utilities/structures/shared.ts diff --git a/packages/backend-core/tests/utilities/structures/sso.ts b/packages/backend-core/tests/core/utilities/structures/sso.ts similarity index 100% rename from packages/backend-core/tests/utilities/structures/sso.ts rename to packages/backend-core/tests/core/utilities/structures/sso.ts diff --git a/packages/backend-core/tests/utilities/structures/tenants.ts b/packages/backend-core/tests/core/utilities/structures/tenants.ts similarity index 50% rename from packages/backend-core/tests/utilities/structures/tenants.ts rename to packages/backend-core/tests/core/utilities/structures/tenants.ts index b23bc8be75..ec2e67109b 100644 --- a/packages/backend-core/tests/utilities/structures/tenants.ts +++ b/packages/backend-core/tests/core/utilities/structures/tenants.ts @@ -1,4 +1,4 @@ -import { newid } from "../../../src/newid" +import { newid } from "../../../../src/docIds/newid" export function id() { return `tenant-${newid()}` diff --git a/packages/backend-core/tests/utilities/structures/userGroups.ts b/packages/backend-core/tests/core/utilities/structures/userGroups.ts similarity index 100% rename from packages/backend-core/tests/utilities/structures/userGroups.ts rename to packages/backend-core/tests/core/utilities/structures/userGroups.ts diff --git a/packages/backend-core/tests/utilities/structures/users.ts b/packages/backend-core/tests/core/utilities/structures/users.ts similarity index 100% rename from packages/backend-core/tests/utilities/structures/users.ts rename to packages/backend-core/tests/core/utilities/structures/users.ts diff --git a/packages/backend-core/tests/utilities/testContainerUtils.ts b/packages/backend-core/tests/core/utilities/testContainerUtils.ts similarity index 100% rename from packages/backend-core/tests/utilities/testContainerUtils.ts rename to packages/backend-core/tests/core/utilities/testContainerUtils.ts diff --git a/packages/backend-core/tests/utilities/DBTestConfiguration.ts b/packages/backend-core/tests/extra/DBTestConfiguration.ts similarity index 87% rename from packages/backend-core/tests/utilities/DBTestConfiguration.ts rename to packages/backend-core/tests/extra/DBTestConfiguration.ts index e5e57a99a3..a2550a6e24 100644 --- a/packages/backend-core/tests/utilities/DBTestConfiguration.ts +++ b/packages/backend-core/tests/extra/DBTestConfiguration.ts @@ -1,5 +1,5 @@ -import "./mocks" -import * as structures from "./structures" +import "../core/utilities/mocks" +import * as structures from "../core/utilities/structures" import * as testEnv from "./testEnv" import * as context from "../../src/context" diff --git a/packages/backend-core/tests/extra/index.ts b/packages/backend-core/tests/extra/index.ts new file mode 100644 index 0000000000..b5d734090c --- /dev/null +++ b/packages/backend-core/tests/extra/index.ts @@ -0,0 +1,2 @@ +export * as testEnv from "./testEnv" +export { default as DBTestConfiguration } from "./DBTestConfiguration" diff --git a/packages/backend-core/tests/utilities/testEnv.ts b/packages/backend-core/tests/extra/testEnv.ts similarity index 98% rename from packages/backend-core/tests/utilities/testEnv.ts rename to packages/backend-core/tests/extra/testEnv.ts index b138e019fc..2b9628e44d 100644 --- a/packages/backend-core/tests/utilities/testEnv.ts +++ b/packages/backend-core/tests/extra/testEnv.ts @@ -1,6 +1,6 @@ import env from "../../src/environment" import * as context from "../../src/context" -import * as structures from "./structures" +import * as structures from "../core/utilities/structures" // TENANCY diff --git a/packages/backend-core/tests/index.ts b/packages/backend-core/tests/index.ts index b23d52e6e0..50fc1dc431 100644 --- a/packages/backend-core/tests/index.ts +++ b/packages/backend-core/tests/index.ts @@ -1 +1 @@ -export * from "./utilities" +export * from "./core/utilities" diff --git a/packages/backend-core/tests/jestSetup.ts b/packages/backend-core/tests/jestSetup.ts index f5542e8fdd..42a24ce733 100644 --- a/packages/backend-core/tests/jestSetup.ts +++ b/packages/backend-core/tests/jestSetup.ts @@ -1,6 +1,7 @@ +import "./core/logging" import env from "../src/environment" import { cleanup } from "../src/timers" -import { mocks, testContainerUtils } from "./utilities" +import { mocks, testContainerUtils } from "./core/utilities" // must explicitly enable fetch mock mocks.fetch.enable() diff --git a/packages/backend-core/tests/utilities/mocks/alerts.ts b/packages/backend-core/tests/utilities/mocks/alerts.ts deleted file mode 100644 index 501c543671..0000000000 --- a/packages/backend-core/tests/utilities/mocks/alerts.ts +++ /dev/null @@ -1,3 +0,0 @@ -jest.mock("../../../src/logging/alerts") -import * as _alerts from "../../../src/logging/alerts" -export const alerts = jest.mocked(_alerts) diff --git a/packages/backend-core/tests/utilities/mocks/events.ts b/packages/backend-core/tests/utilities/mocks/events.ts deleted file mode 100644 index ab0aaa93a6..0000000000 --- a/packages/backend-core/tests/utilities/mocks/events.ts +++ /dev/null @@ -1,122 +0,0 @@ -import * as processors from "../../../src/events/processors" -import * as events from "../../../src/events" - -jest.spyOn(processors.analyticsProcessor, "processEvent") - -jest.spyOn(events.identification, "identifyTenantGroup") -jest.spyOn(events.identification, "identifyUser") - -jest.spyOn(events.backfill, "appSucceeded") -jest.spyOn(events.backfill, "tenantSucceeded") - -jest.spyOn(events.account, "created") -jest.spyOn(events.account, "deleted") -jest.spyOn(events.account, "verified") - -jest.spyOn(events.app, "created") -jest.spyOn(events.app, "updated") -jest.spyOn(events.app, "deleted") -jest.spyOn(events.app, "published") -jest.spyOn(events.app, "unpublished") -jest.spyOn(events.app, "templateImported") -jest.spyOn(events.app, "fileImported") -jest.spyOn(events.app, "versionUpdated") -jest.spyOn(events.app, "versionReverted") -jest.spyOn(events.app, "reverted") -jest.spyOn(events.app, "exported") - -jest.spyOn(events.auth, "login") -jest.spyOn(events.auth, "logout") -jest.spyOn(events.auth, "SSOCreated") -jest.spyOn(events.auth, "SSOUpdated") -jest.spyOn(events.auth, "SSOActivated") -jest.spyOn(events.auth, "SSODeactivated") - -jest.spyOn(events.automation, "created") -jest.spyOn(events.automation, "deleted") -jest.spyOn(events.automation, "tested") -jest.spyOn(events.automation, "stepCreated") -jest.spyOn(events.automation, "stepDeleted") -jest.spyOn(events.automation, "triggerUpdated") - -jest.spyOn(events.datasource, "created") -jest.spyOn(events.datasource, "updated") -jest.spyOn(events.datasource, "deleted") - -jest.spyOn(events.email, "SMTPCreated") -jest.spyOn(events.email, "SMTPUpdated") - -jest.spyOn(events.layout, "created") -jest.spyOn(events.layout, "deleted") - -jest.spyOn(events.org, "nameUpdated") -jest.spyOn(events.org, "logoUpdated") -jest.spyOn(events.org, "platformURLUpdated") -jest.spyOn(events.org, "analyticsOptOut") - -jest.spyOn(events.installation, "versionChecked") - -jest.spyOn(events.query, "created") -jest.spyOn(events.query, "updated") -jest.spyOn(events.query, "deleted") -jest.spyOn(events.query, "imported") -jest.spyOn(events.query, "previewed") - -jest.spyOn(events.role, "created") -jest.spyOn(events.role, "updated") -jest.spyOn(events.role, "deleted") -jest.spyOn(events.role, "assigned") -jest.spyOn(events.role, "unassigned") - -jest.spyOn(events.rows, "imported") -jest.spyOn(events.rows, "created") - -jest.spyOn(events.screen, "created") -jest.spyOn(events.screen, "deleted") - -jest.spyOn(events.user, "created") -jest.spyOn(events.user, "updated") -jest.spyOn(events.user, "deleted") -jest.spyOn(events.user, "permissionAdminAssigned") -jest.spyOn(events.user, "permissionAdminRemoved") -jest.spyOn(events.user, "permissionBuilderAssigned") -jest.spyOn(events.user, "permissionBuilderRemoved") -jest.spyOn(events.user, "invited") -jest.spyOn(events.user, "inviteAccepted") -jest.spyOn(events.user, "passwordForceReset") -jest.spyOn(events.user, "passwordUpdated") -jest.spyOn(events.user, "passwordResetRequested") -jest.spyOn(events.user, "passwordReset") - -jest.spyOn(events.group, "created") -jest.spyOn(events.group, "updated") -jest.spyOn(events.group, "deleted") -jest.spyOn(events.group, "usersAdded") -jest.spyOn(events.group, "usersDeleted") -jest.spyOn(events.group, "createdOnboarding") -jest.spyOn(events.group, "permissionsEdited") - -jest.spyOn(events.serve, "servedBuilder") -jest.spyOn(events.serve, "servedApp") -jest.spyOn(events.serve, "servedAppPreview") - -jest.spyOn(events.table, "created") -jest.spyOn(events.table, "updated") -jest.spyOn(events.table, "deleted") -jest.spyOn(events.table, "exported") -jest.spyOn(events.table, "imported") - -jest.spyOn(events.view, "created") -jest.spyOn(events.view, "updated") -jest.spyOn(events.view, "deleted") -jest.spyOn(events.view, "exported") -jest.spyOn(events.view, "filterCreated") -jest.spyOn(events.view, "filterUpdated") -jest.spyOn(events.view, "filterDeleted") -jest.spyOn(events.view, "calculationCreated") -jest.spyOn(events.view, "calculationUpdated") -jest.spyOn(events.view, "calculationDeleted") - -jest.spyOn(events.plugin, "init") -jest.spyOn(events.plugin, "imported") -jest.spyOn(events.plugin, "deleted") diff --git a/packages/backend-core/tests/utilities/mocks/fetch.ts b/packages/backend-core/tests/utilities/mocks/fetch.ts deleted file mode 100644 index eeb0ccda45..0000000000 --- a/packages/backend-core/tests/utilities/mocks/fetch.ts +++ /dev/null @@ -1,10 +0,0 @@ -const mockFetch = jest.fn() - -const enable = () => { - jest.mock("node-fetch", () => mockFetch) -} - -export default { - ...mockFetch, - enable, -} diff --git a/packages/backend-core/yarn.lock b/packages/backend-core/yarn.lock index b7ac2a859b..2f2f2bbc87 100644 --- a/packages/backend-core/yarn.lock +++ b/packages/backend-core/yarn.lock @@ -201,6 +201,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz#86c2347da5acbf5583ba0a10aed4c9bf9da9cf96" integrity sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA== +"@babel/helper-plugin-utils@^7.18.6": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" + integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== + "@babel/helper-simple-access@^7.17.7": version "7.18.2" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz#4dc473c2169ac3a1c9f4a51cfcd091d1c36fcff9" @@ -335,6 +340,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" +"@babel/plugin-syntax-jsx@^7.7.2": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" + integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" @@ -535,50 +547,49 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.1.3.tgz#2030606ec03a18c31803b8a36382762e447655df" - integrity sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw== +"@jest/console@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.5.0.tgz#593a6c5c0d3f75689835f1b3b4688c4f8544cb57" + integrity sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ== dependencies: - "@jest/types" "^28.1.3" + "@jest/types" "^29.5.0" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^28.1.3" - jest-util "^28.1.3" + jest-message-util "^29.5.0" + jest-util "^29.5.0" slash "^3.0.0" -"@jest/core@^28.1.1", "@jest/core@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-28.1.3.tgz#0ebf2bd39840f1233cd5f2d1e6fc8b71bd5a1ac7" - integrity sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA== +"@jest/core@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.5.0.tgz#76674b96904484e8214614d17261cc491e5f1f03" + integrity sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ== dependencies: - "@jest/console" "^28.1.3" - "@jest/reporters" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/console" "^29.5.0" + "@jest/reporters" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" ci-info "^3.2.0" exit "^0.1.2" graceful-fs "^4.2.9" - jest-changed-files "^28.1.3" - jest-config "^28.1.3" - jest-haste-map "^28.1.3" - jest-message-util "^28.1.3" - jest-regex-util "^28.0.2" - jest-resolve "^28.1.3" - jest-resolve-dependencies "^28.1.3" - jest-runner "^28.1.3" - jest-runtime "^28.1.3" - jest-snapshot "^28.1.3" - jest-util "^28.1.3" - jest-validate "^28.1.3" - jest-watcher "^28.1.3" + jest-changed-files "^29.5.0" + jest-config "^29.5.0" + jest-haste-map "^29.5.0" + jest-message-util "^29.5.0" + jest-regex-util "^29.4.3" + jest-resolve "^29.5.0" + jest-resolve-dependencies "^29.5.0" + jest-runner "^29.5.0" + jest-runtime "^29.5.0" + jest-snapshot "^29.5.0" + jest-util "^29.5.0" + jest-validate "^29.5.0" + jest-watcher "^29.5.0" micromatch "^4.0.4" - pretty-format "^28.1.3" - rimraf "^3.0.0" + pretty-format "^29.5.0" slash "^3.0.0" strip-ansi "^6.0.0" @@ -589,63 +600,64 @@ dependencies: "@jest/types" "^27.5.1" -"@jest/environment@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-28.1.3.tgz#abed43a6b040a4c24fdcb69eab1f97589b2d663e" - integrity sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA== +"@jest/environment@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.5.0.tgz#9152d56317c1fdb1af389c46640ba74ef0bb4c65" + integrity sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ== dependencies: - "@jest/fake-timers" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/fake-timers" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" - jest-mock "^28.1.3" + jest-mock "^29.5.0" -"@jest/expect-utils@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.3.tgz#58561ce5db7cd253a7edddbc051fb39dda50f525" - integrity sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA== +"@jest/expect-utils@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.5.0.tgz#f74fad6b6e20f924582dc8ecbf2cb800fe43a036" + integrity sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg== dependencies: - jest-get-type "^28.0.2" + jest-get-type "^29.4.3" -"@jest/expect@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-28.1.3.tgz#9ac57e1d4491baca550f6bdbd232487177ad6a72" - integrity sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw== +"@jest/expect@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.5.0.tgz#80952f5316b23c483fbca4363ce822af79c38fba" + integrity sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g== dependencies: - expect "^28.1.3" - jest-snapshot "^28.1.3" + expect "^29.5.0" + jest-snapshot "^29.5.0" -"@jest/fake-timers@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-28.1.3.tgz#230255b3ad0a3d4978f1d06f70685baea91c640e" - integrity sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw== +"@jest/fake-timers@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.5.0.tgz#d4d09ec3286b3d90c60bdcd66ed28d35f1b4dc2c" + integrity sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg== dependencies: - "@jest/types" "^28.1.3" - "@sinonjs/fake-timers" "^9.1.2" + "@jest/types" "^29.5.0" + "@sinonjs/fake-timers" "^10.0.2" "@types/node" "*" - jest-message-util "^28.1.3" - jest-mock "^28.1.3" - jest-util "^28.1.3" + jest-message-util "^29.5.0" + jest-mock "^29.5.0" + jest-util "^29.5.0" -"@jest/globals@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-28.1.3.tgz#a601d78ddc5fdef542728309894895b4a42dc333" - integrity sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA== +"@jest/globals@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.5.0.tgz#6166c0bfc374c58268677539d0c181f9c1833298" + integrity sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ== dependencies: - "@jest/environment" "^28.1.3" - "@jest/expect" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/environment" "^29.5.0" + "@jest/expect" "^29.5.0" + "@jest/types" "^29.5.0" + jest-mock "^29.5.0" -"@jest/reporters@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-28.1.3.tgz#9adf6d265edafc5fc4a434cfb31e2df5a67a369a" - integrity sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg== +"@jest/reporters@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.5.0.tgz#985dfd91290cd78ddae4914ba7921bcbabe8ac9b" + integrity sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" - "@jridgewell/trace-mapping" "^0.3.13" + "@jest/console" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" + "@jridgewell/trace-mapping" "^0.3.15" "@types/node" "*" chalk "^4.0.0" collect-v8-coverage "^1.0.0" @@ -657,71 +669,70 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.1.3" - jest-message-util "^28.1.3" - jest-util "^28.1.3" - jest-worker "^28.1.3" + jest-message-util "^29.5.0" + jest-util "^29.5.0" + jest-worker "^29.5.0" slash "^3.0.0" string-length "^4.0.1" strip-ansi "^6.0.0" - terminal-link "^2.0.0" v8-to-istanbul "^9.0.1" -"@jest/schemas@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.1.3.tgz#ad8b86a66f11f33619e3d7e1dcddd7f2d40ff905" - integrity sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg== +"@jest/schemas@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.3.tgz#39cf1b8469afc40b6f5a2baaa146e332c4151788" + integrity sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg== dependencies: - "@sinclair/typebox" "^0.24.1" + "@sinclair/typebox" "^0.25.16" -"@jest/source-map@^28.1.2": - version "28.1.2" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-28.1.2.tgz#7fe832b172b497d6663cdff6c13b0a920e139e24" - integrity sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww== +"@jest/source-map@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.4.3.tgz#ff8d05cbfff875d4a791ab679b4333df47951d20" + integrity sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w== dependencies: - "@jridgewell/trace-mapping" "^0.3.13" + "@jridgewell/trace-mapping" "^0.3.15" callsites "^3.0.0" graceful-fs "^4.2.9" -"@jest/test-result@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.1.3.tgz#5eae945fd9f4b8fcfce74d239e6f725b6bf076c5" - integrity sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg== +"@jest/test-result@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.5.0.tgz#7c856a6ca84f45cc36926a4e9c6b57f1973f1408" + integrity sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ== dependencies: - "@jest/console" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/console" "^29.5.0" + "@jest/types" "^29.5.0" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz#9d0c283d906ac599c74bde464bc0d7e6a82886c3" - integrity sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw== +"@jest/test-sequencer@29.5.0", "@jest/test-sequencer@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz#34d7d82d3081abd523dbddc038a3ddcb9f6d3cc4" + integrity sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ== dependencies: - "@jest/test-result" "^28.1.3" + "@jest/test-result" "^29.5.0" graceful-fs "^4.2.9" - jest-haste-map "^28.1.3" + jest-haste-map "^29.5.0" slash "^3.0.0" -"@jest/transform@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-28.1.3.tgz#59d8098e50ab07950e0f2fc0fc7ec462371281b0" - integrity sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA== +"@jest/transform@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.5.0.tgz#cf9c872d0965f0cbd32f1458aa44a2b1988b00f9" + integrity sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw== dependencies: "@babel/core" "^7.11.6" - "@jest/types" "^28.1.3" - "@jridgewell/trace-mapping" "^0.3.13" + "@jest/types" "^29.5.0" + "@jridgewell/trace-mapping" "^0.3.15" babel-plugin-istanbul "^6.1.1" chalk "^4.0.0" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" + convert-source-map "^2.0.0" + fast-json-stable-stringify "^2.1.0" graceful-fs "^4.2.9" - jest-haste-map "^28.1.3" - jest-regex-util "^28.0.2" - jest-util "^28.1.3" + jest-haste-map "^29.5.0" + jest-regex-util "^29.4.3" + jest-util "^29.5.0" micromatch "^4.0.4" pirates "^4.0.4" slash "^3.0.0" - write-file-atomic "^4.0.1" + write-file-atomic "^4.0.2" "@jest/types@^27.5.1": version "27.5.1" @@ -734,12 +745,12 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" -"@jest/types@^28.1.1", "@jest/types@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b" - integrity sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ== +"@jest/types@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.5.0.tgz#f59ef9b031ced83047c67032700d8c807d6e1593" + integrity sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog== dependencies: - "@jest/schemas" "^28.1.3" + "@jest/schemas" "^29.4.3" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" @@ -810,7 +821,7 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.13": +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15": version "0.3.17" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== @@ -896,29 +907,29 @@ resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== -"@sinclair/typebox@^0.24.1": - version "0.24.51" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" - integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== +"@sinclair/typebox@^0.25.16": + version "0.25.24" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" + integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== -"@sinonjs/commons@^1.7.0": - version "1.8.3" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" - integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== +"@sinonjs/commons@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3" + integrity sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg== dependencies: type-detect "4.0.8" -"@sinonjs/fake-timers@^9.1.2": - version "9.1.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" - integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== +"@sinonjs/fake-timers@^10.0.2": + version "10.0.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz#d10549ed1f423d80639c528b6c7f5a1017747d0c" + integrity sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw== dependencies: - "@sinonjs/commons" "^1.7.0" + "@sinonjs/commons" "^2.0.0" "@swc/core-darwin-arm64@1.3.25": version "1.3.25" @@ -1737,15 +1748,15 @@ axios@^1.1.3: form-data "^4.0.0" proxy-from-env "^1.1.0" -babel-jest@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-28.1.3.tgz#c1187258197c099072156a0a121c11ee1e3917d5" - integrity sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q== +babel-jest@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.5.0.tgz#3fe3ddb109198e78b1c88f9ebdecd5e4fc2f50a5" + integrity sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q== dependencies: - "@jest/transform" "^28.1.3" + "@jest/transform" "^29.5.0" "@types/babel__core" "^7.1.14" babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^28.1.3" + babel-preset-jest "^29.5.0" chalk "^4.0.0" graceful-fs "^4.2.9" slash "^3.0.0" @@ -1761,10 +1772,10 @@ babel-plugin-istanbul@^6.1.1: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz#1952c4d0ea50f2d6d794353762278d1d8cca3fbe" - integrity sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q== +babel-plugin-jest-hoist@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz#a97db437936f441ec196990c9738d4b88538618a" + integrity sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" @@ -1789,12 +1800,12 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-top-level-await" "^7.8.3" -babel-preset-jest@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz#5dfc20b99abed5db994406c2b9ab94c73aaa419d" - integrity sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A== +babel-preset-jest@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz#57bc8cc88097af7ff6a5ab59d1cd29d52a5916e2" + integrity sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg== dependencies: - babel-plugin-jest-hoist "^28.1.3" + babel-plugin-jest-hoist "^29.5.0" babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: @@ -2239,13 +2250,18 @@ content-type@^1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== -convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: +convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.8.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== dependencies: safe-buffer "~5.1.1" +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + cookies@~0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.8.0.tgz#1293ce4b391740a8406e3c9870e828c4b54f3f90" @@ -2434,10 +2450,10 @@ diff-sequences@^27.5.1: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== -diff-sequences@^28.1.1: - version "28.1.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6" - integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw== +diff-sequences@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2" + integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA== diff@^4.0.1: version "4.0.2" @@ -2539,10 +2555,10 @@ emitter-listener@1.1.2: dependencies: shimmer "^1.2.0" -emittery@^0.10.2: - version "0.10.2" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" - integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== emoji-regex@^8.0.0: version "8.0.0" @@ -2664,16 +2680,16 @@ expand-tilde@^1.2.2: dependencies: os-homedir "^1.0.1" -expect@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/expect/-/expect-28.1.3.tgz#90a7c1a124f1824133dd4533cce2d2bdcb6603ec" - integrity sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g== +expect@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.5.0.tgz#68c0509156cb2a0adb8865d413b137eeaae682f7" + integrity sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg== dependencies: - "@jest/expect-utils" "^28.1.3" - jest-get-type "^28.0.2" - jest-matcher-utils "^28.1.3" - jest-message-util "^28.1.3" - jest-util "^28.1.3" + "@jest/expect-utils" "^29.5.0" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.5.0" + jest-message-util "^29.5.0" + jest-util "^29.5.0" extend@~3.0.2: version "3.0.2" @@ -2700,7 +2716,7 @@ fast-deep-equal@^3.1.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -3433,82 +3449,83 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-changed-files@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-28.1.3.tgz#d9aeee6792be3686c47cb988a8eaf82ff4238831" - integrity sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA== +jest-changed-files@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.5.0.tgz#e88786dca8bf2aa899ec4af7644e16d9dcf9b23e" + integrity sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag== dependencies: execa "^5.0.0" p-limit "^3.1.0" -jest-circus@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-28.1.3.tgz#d14bd11cf8ee1a03d69902dc47b6bd4634ee00e4" - integrity sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow== +jest-circus@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.5.0.tgz#b5926989449e75bff0d59944bae083c9d7fb7317" + integrity sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA== dependencies: - "@jest/environment" "^28.1.3" - "@jest/expect" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/environment" "^29.5.0" + "@jest/expect" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^0.7.0" is-generator-fn "^2.0.0" - jest-each "^28.1.3" - jest-matcher-utils "^28.1.3" - jest-message-util "^28.1.3" - jest-runtime "^28.1.3" - jest-snapshot "^28.1.3" - jest-util "^28.1.3" + jest-each "^29.5.0" + jest-matcher-utils "^29.5.0" + jest-message-util "^29.5.0" + jest-runtime "^29.5.0" + jest-snapshot "^29.5.0" + jest-util "^29.5.0" p-limit "^3.1.0" - pretty-format "^28.1.3" + pretty-format "^29.5.0" + pure-rand "^6.0.0" slash "^3.0.0" stack-utils "^2.0.3" -jest-cli@^28.1.1: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-28.1.3.tgz#558b33c577d06de55087b8448d373b9f654e46b2" - integrity sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ== +jest-cli@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.5.0.tgz#b34c20a6d35968f3ee47a7437ff8e53e086b4a67" + integrity sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw== dependencies: - "@jest/core" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/core" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/types" "^29.5.0" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.9" import-local "^3.0.2" - jest-config "^28.1.3" - jest-util "^28.1.3" - jest-validate "^28.1.3" + jest-config "^29.5.0" + jest-util "^29.5.0" + jest-validate "^29.5.0" prompts "^2.0.1" yargs "^17.3.1" -jest-config@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-28.1.3.tgz#e315e1f73df3cac31447eed8b8740a477392ec60" - integrity sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ== +jest-config@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.5.0.tgz#3cc972faec8c8aaea9ae158c694541b79f3748da" + integrity sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA== dependencies: "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^28.1.3" - "@jest/types" "^28.1.3" - babel-jest "^28.1.3" + "@jest/test-sequencer" "^29.5.0" + "@jest/types" "^29.5.0" + babel-jest "^29.5.0" chalk "^4.0.0" ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.3" graceful-fs "^4.2.9" - jest-circus "^28.1.3" - jest-environment-node "^28.1.3" - jest-get-type "^28.0.2" - jest-regex-util "^28.0.2" - jest-resolve "^28.1.3" - jest-runner "^28.1.3" - jest-util "^28.1.3" - jest-validate "^28.1.3" + jest-circus "^29.5.0" + jest-environment-node "^29.5.0" + jest-get-type "^29.4.3" + jest-regex-util "^29.4.3" + jest-resolve "^29.5.0" + jest-runner "^29.5.0" + jest-util "^29.5.0" + jest-validate "^29.5.0" micromatch "^4.0.4" parse-json "^5.2.0" - pretty-format "^28.1.3" + pretty-format "^29.5.0" slash "^3.0.0" strip-json-comments "^3.1.1" @@ -3522,82 +3539,82 @@ jest-diff@^27.5.1: jest-get-type "^27.5.1" pretty-format "^27.5.1" -jest-diff@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.1.3.tgz#948a192d86f4e7a64c5264ad4da4877133d8792f" - integrity sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw== +jest-diff@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.5.0.tgz#e0d83a58eb5451dcc1fa61b1c3ee4e8f5a290d63" + integrity sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw== dependencies: chalk "^4.0.0" - diff-sequences "^28.1.1" - jest-get-type "^28.0.2" - pretty-format "^28.1.3" + diff-sequences "^29.4.3" + jest-get-type "^29.4.3" + pretty-format "^29.5.0" -jest-docblock@^28.1.1: - version "28.1.1" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-28.1.1.tgz#6f515c3bf841516d82ecd57a62eed9204c2f42a8" - integrity sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA== +jest-docblock@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.4.3.tgz#90505aa89514a1c7dceeac1123df79e414636ea8" + integrity sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg== dependencies: detect-newline "^3.0.0" -jest-each@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-28.1.3.tgz#bdd1516edbe2b1f3569cfdad9acd543040028f81" - integrity sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g== +jest-each@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.5.0.tgz#fc6e7014f83eac68e22b7195598de8554c2e5c06" + integrity sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA== dependencies: - "@jest/types" "^28.1.3" + "@jest/types" "^29.5.0" chalk "^4.0.0" - jest-get-type "^28.0.2" - jest-util "^28.1.3" - pretty-format "^28.1.3" + jest-get-type "^29.4.3" + jest-util "^29.5.0" + pretty-format "^29.5.0" -jest-environment-node@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-28.1.3.tgz#7e74fe40eb645b9d56c0c4b70ca4357faa349be5" - integrity sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A== +jest-environment-node@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.5.0.tgz#f17219d0f0cc0e68e0727c58b792c040e332c967" + integrity sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw== dependencies: - "@jest/environment" "^28.1.3" - "@jest/fake-timers" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/environment" "^29.5.0" + "@jest/fake-timers" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" - jest-mock "^28.1.3" - jest-util "^28.1.3" + jest-mock "^29.5.0" + jest-util "^29.5.0" jest-get-type@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== -jest-get-type@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-28.0.2.tgz#34622e628e4fdcd793d46db8a242227901fcf203" - integrity sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA== +jest-get-type@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" + integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== -jest-haste-map@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-28.1.3.tgz#abd5451129a38d9841049644f34b034308944e2b" - integrity sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA== +jest-haste-map@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.5.0.tgz#69bd67dc9012d6e2723f20a945099e972b2e94de" + integrity sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA== dependencies: - "@jest/types" "^28.1.3" + "@jest/types" "^29.5.0" "@types/graceful-fs" "^4.1.3" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.9" - jest-regex-util "^28.0.2" - jest-util "^28.1.3" - jest-worker "^28.1.3" + jest-regex-util "^29.4.3" + jest-util "^29.5.0" + jest-worker "^29.5.0" micromatch "^4.0.4" walker "^1.0.8" optionalDependencies: fsevents "^2.3.2" -jest-leak-detector@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz#a6685d9b074be99e3adee816ce84fd30795e654d" - integrity sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA== +jest-leak-detector@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz#cf4bdea9615c72bac4a3a7ba7e7930f9c0610c8c" + integrity sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow== dependencies: - jest-get-type "^28.0.2" - pretty-format "^28.1.3" + jest-get-type "^29.4.3" + pretty-format "^29.5.0" jest-matcher-utils@^27.0.0: version "27.5.1" @@ -3609,124 +3626,125 @@ jest-matcher-utils@^27.0.0: jest-get-type "^27.5.1" pretty-format "^27.5.1" -jest-matcher-utils@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz#5a77f1c129dd5ba3b4d7fc20728806c78893146e" - integrity sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw== +jest-matcher-utils@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz#d957af7f8c0692c5453666705621ad4abc2c59c5" + integrity sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw== dependencies: chalk "^4.0.0" - jest-diff "^28.1.3" - jest-get-type "^28.0.2" - pretty-format "^28.1.3" + jest-diff "^29.5.0" + jest-get-type "^29.4.3" + pretty-format "^29.5.0" -jest-message-util@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.3.tgz#232def7f2e333f1eecc90649b5b94b0055e7c43d" - integrity sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g== +jest-message-util@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.5.0.tgz#1f776cac3aca332ab8dd2e3b41625435085c900e" + integrity sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^28.1.3" + "@jest/types" "^29.5.0" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^28.1.3" + pretty-format "^29.5.0" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-28.1.3.tgz#d4e9b1fc838bea595c77ab73672ebf513ab249da" - integrity sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA== +jest-mock@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.5.0.tgz#26e2172bcc71d8b0195081ff1f146ac7e1518aed" + integrity sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw== dependencies: - "@jest/types" "^28.1.3" + "@jest/types" "^29.5.0" "@types/node" "*" + jest-util "^29.5.0" jest-pnp-resolver@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== -jest-regex-util@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead" - integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== +jest-regex-util@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.4.3.tgz#a42616141e0cae052cfa32c169945d00c0aa0bb8" + integrity sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg== -jest-resolve-dependencies@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz#8c65d7583460df7275c6ea2791901fa975c1fe66" - integrity sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA== +jest-resolve-dependencies@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz#f0ea29955996f49788bf70996052aa98e7befee4" + integrity sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg== dependencies: - jest-regex-util "^28.0.2" - jest-snapshot "^28.1.3" + jest-regex-util "^29.4.3" + jest-snapshot "^29.5.0" -jest-resolve@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-28.1.3.tgz#cfb36100341ddbb061ec781426b3c31eb51aa0a8" - integrity sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ== +jest-resolve@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.5.0.tgz#b053cc95ad1d5f6327f0ac8aae9f98795475ecdc" + integrity sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w== dependencies: chalk "^4.0.0" graceful-fs "^4.2.9" - jest-haste-map "^28.1.3" + jest-haste-map "^29.5.0" jest-pnp-resolver "^1.2.2" - jest-util "^28.1.3" - jest-validate "^28.1.3" + jest-util "^29.5.0" + jest-validate "^29.5.0" resolve "^1.20.0" - resolve.exports "^1.1.0" + resolve.exports "^2.0.0" slash "^3.0.0" -jest-runner@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-28.1.3.tgz#5eee25febd730b4713a2cdfd76bdd5557840f9a1" - integrity sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA== +jest-runner@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.5.0.tgz#6a57c282eb0ef749778d444c1d758c6a7693b6f8" + integrity sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ== dependencies: - "@jest/console" "^28.1.3" - "@jest/environment" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/console" "^29.5.0" + "@jest/environment" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" chalk "^4.0.0" - emittery "^0.10.2" + emittery "^0.13.1" graceful-fs "^4.2.9" - jest-docblock "^28.1.1" - jest-environment-node "^28.1.3" - jest-haste-map "^28.1.3" - jest-leak-detector "^28.1.3" - jest-message-util "^28.1.3" - jest-resolve "^28.1.3" - jest-runtime "^28.1.3" - jest-util "^28.1.3" - jest-watcher "^28.1.3" - jest-worker "^28.1.3" + jest-docblock "^29.4.3" + jest-environment-node "^29.5.0" + jest-haste-map "^29.5.0" + jest-leak-detector "^29.5.0" + jest-message-util "^29.5.0" + jest-resolve "^29.5.0" + jest-runtime "^29.5.0" + jest-util "^29.5.0" + jest-watcher "^29.5.0" + jest-worker "^29.5.0" p-limit "^3.1.0" source-map-support "0.5.13" -jest-runtime@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-28.1.3.tgz#a57643458235aa53e8ec7821949e728960d0605f" - integrity sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw== +jest-runtime@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.5.0.tgz#c83f943ee0c1da7eb91fa181b0811ebd59b03420" + integrity sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw== dependencies: - "@jest/environment" "^28.1.3" - "@jest/fake-timers" "^28.1.3" - "@jest/globals" "^28.1.3" - "@jest/source-map" "^28.1.2" - "@jest/test-result" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/environment" "^29.5.0" + "@jest/fake-timers" "^29.5.0" + "@jest/globals" "^29.5.0" + "@jest/source-map" "^29.4.3" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" + "@types/node" "*" chalk "^4.0.0" cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" - execa "^5.0.0" glob "^7.1.3" graceful-fs "^4.2.9" - jest-haste-map "^28.1.3" - jest-message-util "^28.1.3" - jest-mock "^28.1.3" - jest-regex-util "^28.0.2" - jest-resolve "^28.1.3" - jest-snapshot "^28.1.3" - jest-util "^28.1.3" + jest-haste-map "^29.5.0" + jest-message-util "^29.5.0" + jest-mock "^29.5.0" + jest-regex-util "^29.4.3" + jest-resolve "^29.5.0" + jest-snapshot "^29.5.0" + jest-util "^29.5.0" slash "^3.0.0" strip-bom "^4.0.0" @@ -3735,91 +3753,92 @@ jest-serial-runner@^1.2.1: resolved "https://registry.yarnpkg.com/jest-serial-runner/-/jest-serial-runner-1.2.1.tgz#0f5f8dbe6f077119bd1fdd7e8518f92353c194d5" integrity sha512-d59fF+7HdjNvQEL7B4WyFE+f8q5tGzlNUqtOnxTrT1ofun7O6/Lgm/j255BBgCY2fmSue/34M7Xy9+VWRByP0Q== -jest-snapshot@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-28.1.3.tgz#17467b3ab8ddb81e2f605db05583d69388fc0668" - integrity sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg== +jest-snapshot@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.5.0.tgz#c9c1ce0331e5b63cd444e2f95a55a73b84b1e8ce" + integrity sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g== dependencies: "@babel/core" "^7.11.6" "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-jsx" "^7.7.2" "@babel/plugin-syntax-typescript" "^7.7.2" "@babel/traverse" "^7.7.2" "@babel/types" "^7.3.3" - "@jest/expect-utils" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/expect-utils" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" "@types/babel__traverse" "^7.0.6" "@types/prettier" "^2.1.5" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^28.1.3" + expect "^29.5.0" graceful-fs "^4.2.9" - jest-diff "^28.1.3" - jest-get-type "^28.0.2" - jest-haste-map "^28.1.3" - jest-matcher-utils "^28.1.3" - jest-message-util "^28.1.3" - jest-util "^28.1.3" + jest-diff "^29.5.0" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.5.0" + jest-message-util "^29.5.0" + jest-util "^29.5.0" natural-compare "^1.4.0" - pretty-format "^28.1.3" + pretty-format "^29.5.0" semver "^7.3.5" -jest-util@^28.0.0, jest-util@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0" - integrity sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ== +jest-util@^29.0.0, jest-util@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.5.0.tgz#24a4d3d92fc39ce90425311b23c27a6e0ef16b8f" + integrity sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ== dependencies: - "@jest/types" "^28.1.3" + "@jest/types" "^29.5.0" "@types/node" "*" chalk "^4.0.0" ci-info "^3.2.0" graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-28.1.3.tgz#e322267fd5e7c64cea4629612c357bbda96229df" - integrity sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA== +jest-validate@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.5.0.tgz#8e5a8f36178d40e47138dc00866a5f3bd9916ffc" + integrity sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ== dependencies: - "@jest/types" "^28.1.3" + "@jest/types" "^29.5.0" camelcase "^6.2.0" chalk "^4.0.0" - jest-get-type "^28.0.2" + jest-get-type "^29.4.3" leven "^3.1.0" - pretty-format "^28.1.3" + pretty-format "^29.5.0" -jest-watcher@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.1.3.tgz#c6023a59ba2255e3b4c57179fc94164b3e73abd4" - integrity sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g== +jest-watcher@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.5.0.tgz#cf7f0f949828ba65ddbbb45c743a382a4d911363" + integrity sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA== dependencies: - "@jest/test-result" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/test-result" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" - emittery "^0.10.2" - jest-util "^28.1.3" + emittery "^0.13.1" + jest-util "^29.5.0" string-length "^4.0.1" -jest-worker@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-28.1.3.tgz#7e3c4ce3fa23d1bb6accb169e7f396f98ed4bb98" - integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g== +jest-worker@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.5.0.tgz#bdaefb06811bd3384d93f009755014d8acb4615d" + integrity sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA== dependencies: "@types/node" "*" + jest-util "^29.5.0" merge-stream "^2.0.0" supports-color "^8.0.0" -jest@28.1.1: - version "28.1.1" - resolved "https://registry.yarnpkg.com/jest/-/jest-28.1.1.tgz#3c39a3a09791e16e9ef283597d24ab19a0df701e" - integrity sha512-qw9YHBnjt6TCbIDMPMpJZqf9E12rh6869iZaN08/vpOGgHJSAaLLUn6H8W3IAEuy34Ls3rct064mZLETkxJ2XA== +jest@29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.5.0.tgz#f75157622f5ce7ad53028f2f8888ab53e1f1f24e" + integrity sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ== dependencies: - "@jest/core" "^28.1.1" - "@jest/types" "^28.1.1" + "@jest/core" "^29.5.0" + "@jest/types" "^29.5.0" import-local "^3.0.2" - jest-cli "^28.1.1" + jest-cli "^29.5.0" jmespath@0.15.0: version "0.15.0" @@ -3900,6 +3919,11 @@ json5@^2.2.1: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + jsonc-parser@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" @@ -5146,13 +5170,12 @@ pretty-format@^27.0.0, pretty-format@^27.5.1: ansi-styles "^5.0.0" react-is "^17.0.1" -pretty-format@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.1.3.tgz#c9fba8cedf99ce50963a11b27d982a9ae90970d5" - integrity sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q== +pretty-format@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.5.0.tgz#283134e74f70e2e3e7229336de0e4fce94ccde5a" + integrity sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw== dependencies: - "@jest/schemas" "^28.1.3" - ansi-regex "^5.0.1" + "@jest/schemas" "^29.4.3" ansi-styles "^5.0.0" react-is "^18.0.0" @@ -5229,6 +5252,11 @@ pupa@^2.1.1: dependencies: escape-goat "^2.0.0" +pure-rand@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.1.tgz#31207dddd15d43f299fdcdb2f572df65030c19af" + integrity sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg== + qs@^6.11.0: version "6.11.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" @@ -5449,10 +5477,10 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve.exports@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" - integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== +resolve.exports@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" + integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== resolve@^1.20.0: version "1.22.0" @@ -5470,7 +5498,7 @@ responselike@^1.0.2: dependencies: lowercase-keys "^1.0.0" -rimraf@^3.0.0, rimraf@^3.0.2: +rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -5808,7 +5836,7 @@ supports-color@^5.3.0, supports-color@^5.5.0: dependencies: has-flag "^3.0.0" -supports-color@^7.0.0, supports-color@^7.1.0: +supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -5822,14 +5850,6 @@ supports-color@^8.0.0: dependencies: has-flag "^4.0.0" -supports-hyperlinks@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" - integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== - dependencies: - has-flag "^4.0.0" - supports-color "^7.0.0" - supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" @@ -5878,14 +5898,6 @@ tar@^6.1.11: mkdirp "^1.0.3" yallist "^4.0.0" -terminal-link@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" - integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== - dependencies: - ansi-escapes "^4.2.1" - supports-hyperlinks "^2.0.0" - test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" @@ -6013,19 +6025,19 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= -ts-jest@28.0.4: - version "28.0.4" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-28.0.4.tgz#0ab705a60fc4b9f3506f35e26edfa9e9c915c31b" - integrity sha512-S6uRDDdCJBvnZqyGjB4VCnwbQrbgdL8WPeP4jevVSpYsBaeGRQAIS08o3Svav2Ex+oXwLgJ/m7F24TNq62kA1A== +ts-jest@29.0.5: + version "29.0.5" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.0.5.tgz#c5557dcec8fe434fcb8b70c3e21c6b143bfce066" + integrity sha512-PL3UciSgIpQ7f6XjVOmbi96vmDHUqAyqDr8YxzopDqX3kfgYtX1cuNeBjP+L9sFXi6nzsGGA6R3fP3DDDJyrxA== dependencies: bs-logger "0.x" fast-json-stable-stringify "2.x" - jest-util "^28.0.0" - json5 "^2.2.1" + jest-util "^29.0.0" + json5 "^2.2.3" lodash.memoize "4.x" make-error "1.x" semver "7.x" - yargs-parser "^20.x" + yargs-parser "^21.0.1" ts-node@10.8.1: version "10.8.1" @@ -6335,7 +6347,7 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -write-file-atomic@^4.0.1: +write-file-atomic@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== @@ -6395,12 +6407,7 @@ yaml@^1.10.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yargs-parser@^20.x: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-parser@^21.1.1: +yargs-parser@^21.0.1, yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 0096c488bd..4a4ffece8a 100644 --- a/packages/bbui/package.json +++ b/packages/bbui/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/bbui", "description": "A UI solution used in the different Budibase projects.", - "version": "2.4.44-alpha.11", + "version": "2.4.44-alpha.16", "license": "MPL-2.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", @@ -38,8 +38,8 @@ ], "dependencies": { "@adobe/spectrum-css-workflow-icons": "1.2.1", - "@budibase/shared-core": "2.4.44-alpha.11", - "@budibase/string-templates": "2.4.44-alpha.11", + "@budibase/shared-core": "2.4.44-alpha.16", + "@budibase/string-templates": "2.4.44-alpha.16", "@spectrum-css/accordion": "3.0.24", "@spectrum-css/actionbutton": "1.0.1", "@spectrum-css/actiongroup": "1.0.1", diff --git a/packages/builder/package.json b/packages/builder/package.json index fb9b0b3edd..603b00c3ac 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "2.4.44-alpha.11", + "version": "2.4.44-alpha.16", "license": "GPL-3.0", "private": true, "scripts": { @@ -58,11 +58,11 @@ } }, "dependencies": { - "@budibase/bbui": "2.4.44-alpha.11", - "@budibase/client": "2.4.44-alpha.11", - "@budibase/frontend-core": "2.4.44-alpha.11", - "@budibase/shared-core": "2.4.44-alpha.11", - "@budibase/string-templates": "2.4.44-alpha.11", + "@budibase/bbui": "2.4.44-alpha.16", + "@budibase/client": "2.4.44-alpha.16", + "@budibase/frontend-core": "2.4.44-alpha.16", + "@budibase/shared-core": "2.4.44-alpha.16", + "@budibase/string-templates": "2.4.44-alpha.16", "@fortawesome/fontawesome-svg-core": "^6.2.1", "@fortawesome/free-brands-svg-icons": "^6.2.1", "@fortawesome/free-solid-svg-icons": "^6.2.1", diff --git a/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationDrawer.svelte b/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationDrawer.svelte index 2624c28e7f..8d9ca7e0cd 100644 --- a/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationDrawer.svelte +++ b/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationDrawer.svelte @@ -65,6 +65,14 @@ label: "Must not contain", value: "notContains", }, + MaxFileSize: { + label: "Max file size (MB)", + value: "maxFileSize", + }, + MaxUploadSize: { + label: "Max total upload size (MB)", + value: "maxUploadSize", + }, } const ConstraintMap = { ["string"]: [ @@ -94,7 +102,11 @@ Constraints.Equal, Constraints.NotEqual, ], - ["attachment"]: [Constraints.Required], + ["attachment"]: [ + Constraints.Required, + Constraints.MaxFileSize, + Constraints.MaxUploadSize, + ], ["link"]: [ Constraints.Required, Constraints.Contains, @@ -283,7 +295,7 @@ disabled={rule.constraint === "required"} on:change={e => (rule.value = e.detail)} /> - {:else if rule.type !== "array" && ["maxLength", "minLength", "regex", "notRegex", "contains", "notContains"].includes(rule.constraint)} + {:else if rule.type !== "array" && ["maxUploadSize", "maxFileSize", "maxLength", "minLength", "regex", "notRegex", "contains", "notContains"].includes(rule.constraint)} { return value == null || value.length <= limit } +// Evaluates a max file size (MB) constraint +const maxFileSizeHandler = (value, rule) => { + const limit = parseType(rule.value, "number") + return ( + value == null || + !value.some(attachment => attachment.size / 1000000 > limit) + ) +} + +// Evaluates a max total upload size (MB) constraint +const maxUploadSizeHandler = (value, rule) => { + const limit = parseType(rule.value, "number") + return ( + value == null || + value.reduce((acc, currentItem) => acc + currentItem.size, 0) / 1000000 <= + limit + ) +} + // Evaluates a min value constraint const minValueHandler = (value, rule) => { // Use same type as the value so that things can be compared @@ -330,6 +349,8 @@ const handlerMap = { contains: containsHandler, notContains: notContainsHandler, json: jsonHandler, + maxFileSize: maxFileSizeHandler, + maxUploadSize: maxUploadSizeHandler, } /** diff --git a/packages/frontend-core/package.json b/packages/frontend-core/package.json index 06bd691802..bea20a8bb1 100644 --- a/packages/frontend-core/package.json +++ b/packages/frontend-core/package.json @@ -1,13 +1,13 @@ { "name": "@budibase/frontend-core", - "version": "2.4.44-alpha.11", + "version": "2.4.44-alpha.16", "description": "Budibase frontend core libraries used in builder and client", "author": "Budibase", "license": "MPL-2.0", "svelte": "src/index.js", "dependencies": { - "@budibase/bbui": "2.4.44-alpha.11", - "@budibase/shared-core": "2.4.44-alpha.11", + "@budibase/bbui": "2.4.44-alpha.16", + "@budibase/shared-core": "2.4.44-alpha.16", "lodash": "^4.17.21", "svelte": "^3.46.2" } diff --git a/packages/sdk/package.json b/packages/sdk/package.json index a029d825af..8933aa8f4d 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/sdk", - "version": "2.4.44-alpha.11", + "version": "2.4.44-alpha.16", "description": "Budibase Public API SDK", "author": "Budibase", "license": "MPL-2.0", diff --git a/packages/server/package.json b/packages/server/package.json index e15990c44c..cda6ab01b7 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "2.4.44-alpha.11", + "version": "2.4.44-alpha.16", "description": "Budibase Web Server", "main": "src/index.ts", "repository": { @@ -45,12 +45,12 @@ "license": "GPL-3.0", "dependencies": { "@apidevtools/swagger-parser": "10.0.3", - "@budibase/backend-core": "2.4.44-alpha.11", - "@budibase/client": "2.4.44-alpha.11", - "@budibase/pro": "2.4.44-alpha.10", - "@budibase/shared-core": "2.4.44-alpha.11", - "@budibase/string-templates": "2.4.44-alpha.11", - "@budibase/types": "2.4.44-alpha.11", + "@budibase/backend-core": "2.4.44-alpha.16", + "@budibase/client": "2.4.44-alpha.16", + "@budibase/pro": "2.4.44-alpha.16", + "@budibase/shared-core": "2.4.44-alpha.16", + "@budibase/string-templates": "2.4.44-alpha.16", + "@budibase/types": "2.4.44-alpha.16", "@bull-board/api": "3.7.0", "@bull-board/koa": "3.9.4", "@elastic/elasticsearch": "7.10.0", diff --git a/packages/server/src/api/routes/tests/automation.spec.js b/packages/server/src/api/routes/tests/automation.spec.js index 84fcbbbcf6..9efc2b0d7e 100644 --- a/packages/server/src/api/routes/tests/automation.spec.js +++ b/packages/server/src/api/routes/tests/automation.spec.js @@ -19,11 +19,14 @@ describe("/automations", () => { afterAll(setup.afterAll) - // For some reason this cannot be a beforeAll or the test "tests the automation successfully" fail - beforeEach(async () => { + beforeAll(async () => { await config.init() }) + beforeEach(() => { + events.automation.deleted.mockClear() + }) + describe("get definitions", () => { it("returns a list of definitions for actions", async () => { const res = await request diff --git a/packages/server/src/integrations/redis.ts b/packages/server/src/integrations/redis.ts index 4704b8e483..73ef2bb55c 100644 --- a/packages/server/src/integrations/redis.ts +++ b/packages/server/src/integrations/redis.ts @@ -6,6 +6,7 @@ interface RedisConfig { port: number username: string password?: string + db?: number } const SCHEMA: Integration = { @@ -32,6 +33,12 @@ const SCHEMA: Integration = { type: "password", required: false, }, + db: { + type: "number", + required: false, + display: "DB", + default: 0, + }, }, query: { create: { @@ -88,6 +95,7 @@ class RedisIntegration { port: this.config.port, username: this.config.username, password: this.config.password, + db: this.config.db, }) } diff --git a/packages/server/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts b/packages/server/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts index 51f6c2d301..fc0f9e1aa9 100644 --- a/packages/server/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts +++ b/packages/server/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts @@ -24,7 +24,7 @@ describe("syncRows", () => { // app 1 const app1 = config.app - await context.doInAppContext(app1.appId, async () => { + await context.doInAppContext(app1!.appId, async () => { await config.createTable() await config.createRow() }) @@ -43,7 +43,7 @@ describe("syncRows", () => { usageDoc = await quotas.getQuotaUsage() expect(usageDoc.usageQuota.rows).toEqual(3) expect( - usageDoc.apps?.[dbCore.getProdAppID(app1.appId)].usageQuota.rows + usageDoc.apps?.[dbCore.getProdAppID(app1!.appId)].usageQuota.rows ).toEqual(1) expect( usageDoc.apps?.[dbCore.getProdAppID(app2.appId)].usageQuota.rows diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock index d9989e8de1..422ff175b4 100644 --- a/packages/server/yarn.lock +++ b/packages/server/yarn.lock @@ -1290,14 +1290,14 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@2.4.44-alpha.10": - version "2.4.44-alpha.10" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.4.44-alpha.10.tgz#02fdc24dad37fa244b9e3c7df731f355c9a5927a" - integrity sha512-mhwXyc366dxy+U8aU74I+tVr0b5TmVEqRH+sY/EG3u6wJgwatyz5e5Pq9srftJX/+nM+jXiu27oIKFUx4v+IkA== +"@budibase/backend-core@2.4.44-alpha.16": + version "2.4.44-alpha.16" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.4.44-alpha.16.tgz#d7cbd0b468ffdb7a472ef99a52a1614e193770c2" + integrity sha512-3S6NqVB1Ulq1a8Gl1r9/eBnlpfvhX0P6lTdeDG/K6u/pOUkJqjDHHNvJ936CeXcS6WQKsSr5GF+649VlylV5eg== dependencies: "@budibase/nano" "10.1.2" "@budibase/pouchdb-replication-stream" "1.2.10" - "@budibase/types" "2.4.44-alpha.10" + "@budibase/types" "2.4.44-alpha.16" "@shopify/jest-koa-mocks" "5.0.1" "@techpass/passport-openidconnect" "0.3.2" aws-cloudfront-sign "2.2.0" @@ -1430,15 +1430,15 @@ pouchdb-promise "^6.0.4" through2 "^2.0.0" -"@budibase/pro@2.4.44-alpha.10": - version "2.4.44-alpha.10" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.4.44-alpha.10.tgz#48bba3422f0f90cb2948c109f7e518b98a1ef37e" - integrity sha512-E+WmuLnYu5B6R/C8h8vtLSNdENANKI71cWbXifPwI8lfnRVZxVyW0v98EWknZWGSpF55y8G8AUlKLTkDDOkZkA== +"@budibase/pro@2.4.44-alpha.16": + version "2.4.44-alpha.16" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.4.44-alpha.16.tgz#b3f9884a279bd2135f229bd62e6696e4a2ce8de2" + integrity sha512-oTRehPQPP2LIgpmssUIQ3cvwebnkdZuE7E0WkDb/RNeID0sYQX4I5GZfeaaOhljcd81wJKXZQYGUo4+9oZwBjQ== dependencies: - "@budibase/backend-core" "2.4.44-alpha.10" + "@budibase/backend-core" "2.4.44-alpha.16" "@budibase/shared-core" "2.4.44-alpha.1" "@budibase/string-templates" "2.4.44-alpha.1" - "@budibase/types" "2.4.44-alpha.10" + "@budibase/types" "2.4.44-alpha.16" "@koa/router" "8.0.8" bull "4.10.1" joi "17.6.0" @@ -1491,10 +1491,10 @@ resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.4.44-alpha.1.tgz#1679657aa180d9c59afa1dffa611bff0638bd933" integrity sha512-Sq+8HfM75EBMoOvKYFwELdlxmVN6wNZMofDjT/2G+9aF+Zfe5Tzw69C+unmdBgcGGjGCHEYWSz4mF0v8FPAGbg== -"@budibase/types@2.4.44-alpha.10": - version "2.4.44-alpha.10" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.4.44-alpha.10.tgz#4f5a13948dc95cbe3a6fe305259159207b37b1d9" - integrity sha512-ZvBRXevf3L/N/4fn0pC96CDYXDrElY7C2pn6JlysLoaJMOr3bSQWf1PaslP1/E9gS7XFIKye1wN9VIWIHa0QLg== +"@budibase/types@2.4.44-alpha.16": + version "2.4.44-alpha.16" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.4.44-alpha.16.tgz#83f3745a67db566a80c34d89390ceb057a1456a9" + integrity sha512-F3phfLOBHsLlXKwIxDAZsNo1hneKe916JJefBSlKetLXDH0AZzHWwh3dpYdw2QKdclTVVJKH9QWrBIH8sZFvYQ== dependencies: scim-patch "^0.7.0" diff --git a/packages/shared-core/package.json b/packages/shared-core/package.json index 8c1c829035..90f75f74b2 100644 --- a/packages/shared-core/package.json +++ b/packages/shared-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/shared-core", - "version": "2.4.44-alpha.11", + "version": "2.4.44-alpha.16", "description": "Shared data utils", "main": "dist/cjs/src/index.js", "types": "dist/mjs/src/index.d.ts", @@ -20,7 +20,7 @@ "dev:builder": "yarn prebuild && concurrently \"tsc -p tsconfig.build.json --watch\" \"tsc -p tsconfig-cjs.build.json --watch\"" }, "dependencies": { - "@budibase/types": "2.4.44-alpha.11" + "@budibase/types": "2.4.44-alpha.16" }, "devDependencies": { "concurrently": "^7.6.0", diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index 9cc24a3edb..5978d49611 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "2.4.44-alpha.11", + "version": "2.4.44-alpha.16", "description": "Handlebars wrapper for Budibase templating.", "main": "src/index.cjs", "module": "dist/bundle.mjs", diff --git a/packages/types/package.json b/packages/types/package.json index da8f6226dd..736b9fd2d1 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/types", - "version": "2.4.44-alpha.11", + "version": "2.4.44-alpha.16", "description": "Budibase types", "main": "dist/cjs/index.js", "types": "dist/mjs/index.d.ts", diff --git a/packages/types/src/api/web/global/scim/users.ts b/packages/types/src/api/web/global/scim/users.ts index 53424934ff..8269d392b0 100644 --- a/packages/types/src/api/web/global/scim/users.ts +++ b/packages/types/src/api/web/global/scim/users.ts @@ -19,10 +19,10 @@ export interface ScimUserResponse extends ScimResource { } userName: string displayName?: string - name: { - formatted: string - familyName: string - givenName: string + name?: { + formatted?: string + familyName?: string + givenName?: string } active: BooleanString emails?: Emails @@ -41,7 +41,7 @@ export interface ScimCreateUserRequest { resourceType: "User" } displayName?: string - name: { + name?: { formatted: string familyName: string givenName: string diff --git a/packages/worker/package.json b/packages/worker/package.json index 7add48f0ca..8cb6c67aa5 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/worker", "email": "hi@budibase.com", - "version": "2.4.44-alpha.11", + "version": "2.4.44-alpha.16", "description": "Budibase background service", "main": "src/index.ts", "repository": { @@ -37,10 +37,10 @@ "author": "Budibase", "license": "GPL-3.0", "dependencies": { - "@budibase/backend-core": "2.4.44-alpha.11", - "@budibase/pro": "2.4.44-alpha.10", - "@budibase/string-templates": "2.4.44-alpha.11", - "@budibase/types": "2.4.44-alpha.11", + "@budibase/backend-core": "2.4.44-alpha.16", + "@budibase/pro": "2.4.44-alpha.16", + "@budibase/string-templates": "2.4.44-alpha.16", + "@budibase/types": "2.4.44-alpha.16", "@koa/router": "8.0.8", "@sentry/node": "6.17.7", "@techpass/passport-openidconnect": "0.3.2", diff --git a/packages/worker/src/api/routes/global/tests/scim.spec.ts b/packages/worker/src/api/routes/global/tests/scim.spec.ts index 6c411a640d..3352951152 100644 --- a/packages/worker/src/api/routes/global/tests/scim.spec.ts +++ b/packages/worker/src/api/routes/global/tests/scim.spec.ts @@ -255,6 +255,45 @@ describe("scim", () => { ) }) + it("a new user can minim information", async () => { + const userData = { + externalId: structures.uuid(), + email: structures.generator.email(), + username: structures.generator.name(), + firstName: undefined, + lastName: undefined, + } + const body = structures.scim.createUserRequest(userData) + + const response = await postScimUser({ body }) + + const expectedScimUser = { + schemas: ["urn:ietf:params:scim:schemas:core:2.0:User"], + id: expect.any(String), + externalId: userData.externalId, + meta: { + resourceType: "User", + created: mocks.date.MOCK_DATE.toISOString(), + lastModified: mocks.date.MOCK_DATE.toISOString(), + }, + userName: userData.username, + active: true, + emails: [ + { + value: userData.email, + type: "work", + primary: true, + }, + ], + } + expect(response).toEqual(expectedScimUser) + + const persistedUsers = await config.api.scimUsersAPI.get() + expect(persistedUsers.Resources).toEqual( + expect.arrayContaining([expectedScimUser]) + ) + }) + it("an event is dispatched", async () => { const body = structures.scim.createUserRequest() @@ -318,6 +357,15 @@ describe("scim", () => { await postScimUser({ body }, { expect: 500 }) }) }) + + it("creating an existing user name returns a conflict", async () => { + const body = structures.scim.createUserRequest() + + await postScimUser({ body }) + + const res = await postScimUser({ body }, { expect: 409 }) + expect((res as any).message).toBe("Email already in use") + }) }) describe("GET /api/global/scim/v2/users/:id", () => { @@ -389,7 +437,7 @@ describe("scim", () => { name: { ...user.name, familyName: newFamilyName, - formatted: `${user.name.givenName} ${newFamilyName}`, + formatted: `${user.name!.givenName} ${newFamilyName}`, }, } expect(response).toEqual(expectedScimUser) diff --git a/packages/worker/src/api/routes/global/tests/users.spec.ts b/packages/worker/src/api/routes/global/tests/users.spec.ts index d1afa0191e..52d77cbae6 100644 --- a/packages/worker/src/api/routes/global/tests/users.spec.ts +++ b/packages/worker/src/api/routes/global/tests/users.spec.ts @@ -48,7 +48,7 @@ describe("/api/global/users", () => { 400 ) - expect(res.body.message).toBe("Unavailable") + expect(res.body.message).toBe(`Unavailable`) expect(sendMailMock).toHaveBeenCalledTimes(0) expect(code).toBeUndefined() expect(events.user.invited).toBeCalledTimes(0) @@ -225,7 +225,9 @@ describe("/api/global/users", () => { const response = await config.api.users.saveUser(user, 400) - expect(response.body.message).toBe(`Unavailable`) + expect(response.body.message).toBe( + `Email already in use: '${user.email}'` + ) expect(events.user.created).toBeCalledTimes(0) }) @@ -237,7 +239,9 @@ describe("/api/global/users", () => { delete user._id const response = await config.api.users.saveUser(user, 400) - expect(response.body.message).toBe(`Unavailable`) + expect(response.body.message).toBe( + `Email already in use: '${user.email}'` + ) expect(events.user.created).toBeCalledTimes(0) }) }) @@ -249,7 +253,9 @@ describe("/api/global/users", () => { const response = await config.api.users.saveUser(user, 400) - expect(response.body.message).toBe(`Unavailable`) + expect(response.body.message).toBe( + `Email already in use: '${user.email}'` + ) expect(events.user.created).toBeCalledTimes(0) }) diff --git a/packages/worker/src/sdk/users/users.ts b/packages/worker/src/sdk/users/users.ts index f05c6b98d2..2150654ae9 100644 --- a/packages/worker/src/sdk/users/users.ts +++ b/packages/worker/src/sdk/users/users.ts @@ -16,6 +16,7 @@ import { ViewName, env as coreEnv, context, + EmailUnavailableError, } from "@budibase/backend-core" import { AccountMetadata, @@ -158,7 +159,7 @@ const validateUniqueUser = async (email: string, tenantId: string) => { if (env.MULTI_TENANCY) { const tenantUser = await getPlatformUser(email) if (tenantUser != null && tenantUser.tenantId !== tenantId) { - throw `Unavailable` + throw new EmailUnavailableError(email) } } @@ -166,7 +167,7 @@ const validateUniqueUser = async (email: string, tenantId: string) => { if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) { const account = await accounts.getAccount(email) if (account && account.verified && account.tenantId !== tenantId) { - throw `Unavailable` + throw new EmailUnavailableError(email) } } } @@ -235,7 +236,7 @@ export const save = async ( // no id was specified - load from email instead dbUser = await usersCore.getGlobalUserByEmail(email) if (dbUser && dbUser._id !== _id) { - throw `Unavailable` + throw new EmailUnavailableError(email) } } diff --git a/packages/worker/yarn.lock b/packages/worker/yarn.lock index 605c183a10..402544ceba 100644 --- a/packages/worker/yarn.lock +++ b/packages/worker/yarn.lock @@ -475,14 +475,14 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@2.4.44-alpha.10": - version "2.4.44-alpha.10" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.4.44-alpha.10.tgz#02fdc24dad37fa244b9e3c7df731f355c9a5927a" - integrity sha512-mhwXyc366dxy+U8aU74I+tVr0b5TmVEqRH+sY/EG3u6wJgwatyz5e5Pq9srftJX/+nM+jXiu27oIKFUx4v+IkA== +"@budibase/backend-core@2.4.44-alpha.16": + version "2.4.44-alpha.16" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.4.44-alpha.16.tgz#d7cbd0b468ffdb7a472ef99a52a1614e193770c2" + integrity sha512-3S6NqVB1Ulq1a8Gl1r9/eBnlpfvhX0P6lTdeDG/K6u/pOUkJqjDHHNvJ936CeXcS6WQKsSr5GF+649VlylV5eg== dependencies: "@budibase/nano" "10.1.2" "@budibase/pouchdb-replication-stream" "1.2.10" - "@budibase/types" "2.4.44-alpha.10" + "@budibase/types" "2.4.44-alpha.16" "@shopify/jest-koa-mocks" "5.0.1" "@techpass/passport-openidconnect" "0.3.2" aws-cloudfront-sign "2.2.0" @@ -565,15 +565,15 @@ pouchdb-promise "^6.0.4" through2 "^2.0.0" -"@budibase/pro@2.4.44-alpha.10": - version "2.4.44-alpha.10" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.4.44-alpha.10.tgz#48bba3422f0f90cb2948c109f7e518b98a1ef37e" - integrity sha512-E+WmuLnYu5B6R/C8h8vtLSNdENANKI71cWbXifPwI8lfnRVZxVyW0v98EWknZWGSpF55y8G8AUlKLTkDDOkZkA== +"@budibase/pro@2.4.44-alpha.16": + version "2.4.44-alpha.16" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.4.44-alpha.16.tgz#b3f9884a279bd2135f229bd62e6696e4a2ce8de2" + integrity sha512-oTRehPQPP2LIgpmssUIQ3cvwebnkdZuE7E0WkDb/RNeID0sYQX4I5GZfeaaOhljcd81wJKXZQYGUo4+9oZwBjQ== dependencies: - "@budibase/backend-core" "2.4.44-alpha.10" + "@budibase/backend-core" "2.4.44-alpha.16" "@budibase/shared-core" "2.4.44-alpha.1" "@budibase/string-templates" "2.4.44-alpha.1" - "@budibase/types" "2.4.44-alpha.10" + "@budibase/types" "2.4.44-alpha.16" "@koa/router" "8.0.8" bull "4.10.1" joi "17.6.0" @@ -608,10 +608,10 @@ resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.4.44-alpha.1.tgz#1679657aa180d9c59afa1dffa611bff0638bd933" integrity sha512-Sq+8HfM75EBMoOvKYFwELdlxmVN6wNZMofDjT/2G+9aF+Zfe5Tzw69C+unmdBgcGGjGCHEYWSz4mF0v8FPAGbg== -"@budibase/types@2.4.44-alpha.10": - version "2.4.44-alpha.10" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.4.44-alpha.10.tgz#4f5a13948dc95cbe3a6fe305259159207b37b1d9" - integrity sha512-ZvBRXevf3L/N/4fn0pC96CDYXDrElY7C2pn6JlysLoaJMOr3bSQWf1PaslP1/E9gS7XFIKye1wN9VIWIHa0QLg== +"@budibase/types@2.4.44-alpha.16": + version "2.4.44-alpha.16" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.4.44-alpha.16.tgz#83f3745a67db566a80c34d89390ceb057a1456a9" + integrity sha512-F3phfLOBHsLlXKwIxDAZsNo1hneKe916JJefBSlKetLXDH0AZzHWwh3dpYdw2QKdclTVVJKH9QWrBIH8sZFvYQ== dependencies: scim-patch "^0.7.0" diff --git a/scripts/releaseHelmChart.js b/scripts/releaseHelmChart.js index 0e469bd012..45ae01df0e 100755 --- a/scripts/releaseHelmChart.js +++ b/scripts/releaseHelmChart.js @@ -2,15 +2,8 @@ const yaml = require("js-yaml") const fs = require("fs") const path = require("path") -const UpgradeTypes = { - MAJOR: "major", - MINOR: "minor", - PATCH: "patch" -} - const CHART_PATH = path.join(__dirname, "../", "charts", "budibase", "Chart.yaml") const UPGRADE_VERSION = process.env.BUDIBASE_RELEASE_VERSION -const UPGRADE_TYPE = process.env.HELM_CHART_UPGRADE_TYPE || UpgradeTypes.PATCH if (!UPGRADE_VERSION) { throw new Error("BUDIBASE_RELEASE_VERSION env var must be set.")