diff --git a/.eslintignore b/.eslintignore index 54824be5c7..579bd55947 100644 --- a/.eslintignore +++ b/.eslintignore @@ -7,4 +7,5 @@ packages/server/client packages/builder/.routify packages/builder/cypress/support/queryLevelTransformerFunction.js packages/builder/cypress/support/queryLevelTransformerFunctionWithData.js -packages/builder/cypress/reports \ No newline at end of file +packages/builder/cypress/reports +packages/sdk/sdk \ No newline at end of file diff --git a/.github/workflows/budibase_ci.yml b/.github/workflows/budibase_ci.yml index 42a0c0a273..475bd4f66a 100644 --- a/.github/workflows/budibase_ci.yml +++ b/.github/workflows/budibase_ci.yml @@ -23,6 +23,15 @@ jobs: build: runs-on: ubuntu-latest + services: + couchdb: + image: ibmcom/couchdb3 + env: + COUCHDB_PASSWORD: budibase + COUCHDB_USER: budibase + ports: + - 4567:5984 + strategy: matrix: node-version: [14.x] @@ -53,13 +62,6 @@ jobs: name: codecov-umbrella verbose: true - # TODO: parallelise this - - name: Cypress run - uses: cypress-io/github-action@v2 - with: - install: false - command: yarn test:e2e:ci - - name: QA Core Integration Tests run: | cd qa-core diff --git a/.github/workflows/release-develop.yml b/.github/workflows/release-develop.yml index 57e65c734e..21c74851e1 100644 --- a/.github/workflows/release-develop.yml +++ b/.github/workflows/release-develop.yml @@ -46,7 +46,8 @@ jobs: - run: yarn - run: yarn bootstrap - run: yarn lint - - run: yarn build + - run: yarn build + - run: yarn build:sdk - run: yarn test - name: Configure AWS Credentials diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 961082e1ef..de288dd7db 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -56,6 +56,7 @@ jobs: - run: yarn bootstrap - run: yarn lint - run: yarn build + - run: yarn build:sdk - run: yarn test - name: Configure AWS Credentials diff --git a/.prettierignore b/.prettierignore index ad36a86b99..3a381d255e 100644 --- a/.prettierignore +++ b/.prettierignore @@ -8,4 +8,5 @@ packages/server/client packages/server/src/definitions/openapi.ts packages/builder/.routify packages/builder/cypress/support/queryLevelTransformerFunction.js -packages/builder/cypress/support/queryLevelTransformerFunctionWithData.js \ No newline at end of file +packages/builder/cypress/support/queryLevelTransformerFunctionWithData.js +packages/sdk/sdk \ No newline at end of file diff --git a/charts/budibase/values.yaml b/charts/budibase/values.yaml index a15504d58c..5c4004cb57 100644 --- a/charts/budibase/values.yaml +++ b/charts/budibase/values.yaml @@ -76,6 +76,7 @@ affinity: {} globals: appVersion: "latest" budibaseEnv: PRODUCTION + tenantFeatureFlags: "*:LICENSING,*:USER_GROUPS" enableAnalytics: "1" sentryDSN: "" posthogToken: "phc_bIjZL7oh2GEUd2vqvTBH8WvrX0fWTFQMs6H5KQxiUxU" diff --git a/hosting/single/runner.sh b/hosting/single/runner.sh index cf82e6701b..e02b33d771 100644 --- a/hosting/single/runner.sh +++ b/hosting/single/runner.sh @@ -1,6 +1,6 @@ #!/bin/bash declare -a ENV_VARS=("COUCHDB_USER" "COUCHDB_PASSWORD" "DATA_DIR" "MINIO_ACCESS_KEY" "MINIO_SECRET_KEY" "INTERNAL_API_KEY" "JWT_SECRET" "REDIS_PASSWORD") -declare -a DOCKER_VARS=("APP_PORT" "APPS_URL" "ARCHITECTURE" "BUDIBASE_ENVIRONMENT" "CLUSTER_PORT" "DEPLOYMENT_ENVIRONMENT" "MINIO_URL" "NODE_ENV" "POSTHOG_TOKEN" "REDIS_URL" "SELF_HOSTED" "WORKER_PORT" "WORKER_URL") +declare -a DOCKER_VARS=("APP_PORT" "APPS_URL" "ARCHITECTURE" "BUDIBASE_ENVIRONMENT" "CLUSTER_PORT" "DEPLOYMENT_ENVIRONMENT" "MINIO_URL" "NODE_ENV" "POSTHOG_TOKEN" "REDIS_URL" "SELF_HOSTED" "WORKER_PORT" "WORKER_URL" "TENANT_FEATURE_FLAGS" "ACCOUNT_PORTAL_URL") # Check the env vars set in Dockerfile have come through, AAS seems to drop them [[ -z "${APP_PORT}" ]] && export APP_PORT=4001 [[ -z "${ARCHITECTURE}" ]] && export ARCHITECTURE=amd @@ -10,6 +10,8 @@ declare -a DOCKER_VARS=("APP_PORT" "APPS_URL" "ARCHITECTURE" "BUDIBASE_ENVIRONME [[ -z "${MINIO_URL}" ]] && export MINIO_URL=http://localhost:9000 [[ -z "${NODE_ENV}" ]] && export NODE_ENV=production [[ -z "${POSTHOG_TOKEN}" ]] && export POSTHOG_TOKEN=phc_bIjZL7oh2GEUd2vqvTBH8WvrX0fWTFQMs6H5KQxiUxU +[[ -z "${TENANT_FEATURE_FLAGS}" ]] && export TENANT_FEATURE_FLAGS="*:LICENSING,*:USER_GROUPS" +[[ -z "${ACCOUNT_PORTAL_URL}" ]] && export ACCOUNT_PORTAL_URL=https://account.budibase.app [[ -z "${REDIS_URL}" ]] && export REDIS_URL=localhost:6379 [[ -z "${SELF_HOSTED}" ]] && export SELF_HOSTED=1 [[ -z "${WORKER_PORT}" ]] && export WORKER_PORT=4002 diff --git a/lerna.json b/lerna.json index cfb146ff82..e09921a3ad 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "1.4.17", + "version": "1.4.18-alpha.0", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/package.json b/package.json index d9b78368ba..579e86802e 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "bootstrap": "lerna bootstrap && lerna link && ./scripts/link-dependencies.sh", "build": "lerna run build", "build:dev": "lerna run prebuild && tsc --build --watch --preserveWatchOutput", + "build:sdk": "lerna run build:sdk", "deps:circular": "madge packages/server/dist/index.js packages/worker/src/index.ts packages/backend-core/dist/src/index.js packages/cli/src/index.js --circular", "release": "lerna publish ${RELEASE_VERSION_TYPE:-patch} --yes --force-publish && yarn release:pro", "release:develop": "lerna publish prerelease --yes --force-publish --dist-tag develop --exact && yarn release:pro:develop", diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 68805eb411..1b41fed027 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "1.4.17", + "version": "1.4.18-alpha.0", "description": "Budibase backend core libraries used in server and worker", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -20,7 +20,7 @@ "test:watch": "jest --watchAll" }, "dependencies": { - "@budibase/types": "^1.4.17", + "@budibase/types": "1.4.18-alpha.0", "@shopify/jest-koa-mocks": "5.0.1", "@techpass/passport-openidconnect": "0.3.2", "aws-sdk": "2.1030.0", diff --git a/packages/backend-core/src/db/constants.ts b/packages/backend-core/src/db/constants.ts index 62f4e8820f..45ca675fa6 100644 --- a/packages/backend-core/src/db/constants.ts +++ b/packages/backend-core/src/db/constants.ts @@ -20,6 +20,7 @@ export enum ViewName { AUTOMATION_LOGS = "automation_logs", ACCOUNT_BY_EMAIL = "account_by_email", PLATFORM_USERS_LOWERCASE = "platform_users_lowercase", + USER_BY_GROUP = "by_group_user", } export const DeprecatedViews = { diff --git a/packages/backend-core/src/db/views.ts b/packages/backend-core/src/db/views.ts index c337d26eaa..f0fff918fc 100644 --- a/packages/backend-core/src/db/views.ts +++ b/packages/backend-core/src/db/views.ts @@ -36,154 +36,91 @@ async function removeDeprecated(db: PouchDB.Database, viewName: ViewName) { } } -export const createNewUserEmailView = async () => { - const db = getGlobalDB() +export async function createView(db: any, viewJs: string, viewName: string) { let designDoc try { - designDoc = await db.get(DESIGN_DB) + designDoc = (await db.get(DESIGN_DB)) as DesignDocument } catch (err) { // no design doc, make one designDoc = DesignDoc() } const view = { - // if using variables in a map function need to inject them before use - map: `function(doc) { - if (doc._id.startsWith("${DocumentType.USER}${SEPARATOR}")) { - emit(doc.email.toLowerCase(), doc._id) - } - }`, + map: viewJs, } designDoc.views = { ...designDoc.views, - [ViewName.USER_BY_EMAIL]: view, + [viewName]: view, } await db.put(designDoc) } +export const createNewUserEmailView = async () => { + const db = getGlobalDB() + const viewJs = `function(doc) { + if (doc._id.startsWith("${DocumentType.USER}${SEPARATOR}")) { + emit(doc.email.toLowerCase(), doc._id) + } + }` + await createView(db, viewJs, ViewName.USER_BY_EMAIL) +} + export const createAccountEmailView = async () => { + const viewJs = `function(doc) { + if (doc._id.startsWith("${DocumentType.ACCOUNT_METADATA}${SEPARATOR}")) { + emit(doc.email.toLowerCase(), doc._id) + } + }` await doWithDB( StaticDatabases.PLATFORM_INFO.name, async (db: PouchDB.Database) => { - let designDoc - try { - designDoc = await db.get(DESIGN_DB) - } catch (err) { - // no design doc, make one - designDoc = DesignDoc() - } - const view = { - // if using variables in a map function need to inject them before use - map: `function(doc) { - if (doc._id.startsWith("${DocumentType.ACCOUNT_METADATA}${SEPARATOR}")) { - emit(doc.email.toLowerCase(), doc._id) - } - }`, - } - designDoc.views = { - ...designDoc.views, - [ViewName.ACCOUNT_BY_EMAIL]: view, - } - await db.put(designDoc) + await createView(db, viewJs, ViewName.ACCOUNT_BY_EMAIL) } ) } export const createUserAppView = async () => { const db = getGlobalDB() as PouchDB.Database - let designDoc - try { - designDoc = await db.get("_design/database") - } catch (err) { - // no design doc, make one - designDoc = DesignDoc() - } - const view = { - // if using variables in a map function need to inject them before use - map: `function(doc) { - if (doc._id.startsWith("${DocumentType.USER}${SEPARATOR}") && doc.roles) { - for (let prodAppId of Object.keys(doc.roles)) { - let emitted = prodAppId + "${SEPARATOR}" + doc._id - emit(emitted, null) - } + const viewJs = `function(doc) { + if (doc._id.startsWith("${DocumentType.USER}${SEPARATOR}") && doc.roles) { + for (let prodAppId of Object.keys(doc.roles)) { + let emitted = prodAppId + "${SEPARATOR}" + doc._id + emit(emitted, null) } - }`, - } - designDoc.views = { - ...designDoc.views, - [ViewName.USER_BY_APP]: view, - } - await db.put(designDoc) + } + }` + await createView(db, viewJs, ViewName.USER_BY_APP) } export const createApiKeyView = async () => { const db = getGlobalDB() - let designDoc - try { - designDoc = await db.get("_design/database") - } catch (err) { - designDoc = DesignDoc() - } - const view = { - map: `function(doc) { - if (doc._id.startsWith("${DocumentType.DEV_INFO}") && doc.apiKey) { - emit(doc.apiKey, doc.userId) - } - }`, - } - designDoc.views = { - ...designDoc.views, - [ViewName.BY_API_KEY]: view, - } - await db.put(designDoc) + const viewJs = `function(doc) { + if (doc._id.startsWith("${DocumentType.DEV_INFO}") && doc.apiKey) { + emit(doc.apiKey, doc.userId) + } + }` + await createView(db, viewJs, ViewName.BY_API_KEY) } export const createUserBuildersView = async () => { const db = getGlobalDB() - let designDoc - try { - designDoc = await db.get("_design/database") - } catch (err) { - // no design doc, make one - designDoc = DesignDoc() - } - const view = { - map: `function(doc) { - if (doc.builder && doc.builder.global === true) { - emit(doc._id, doc._id) - } - }`, - } - designDoc.views = { - ...designDoc.views, - [ViewName.USER_BY_BUILDERS]: view, - } - await db.put(designDoc) + const viewJs = `function(doc) { + if (doc.builder && doc.builder.global === true) { + emit(doc._id, doc._id) + } + }` + await createView(db, viewJs, ViewName.USER_BY_BUILDERS) } export const createPlatformUserView = async () => { + const viewJs = `function(doc) { + if (doc.tenantId) { + emit(doc._id.toLowerCase(), doc._id) + } + }` await doWithDB( StaticDatabases.PLATFORM_INFO.name, async (db: PouchDB.Database) => { - let designDoc - try { - designDoc = await db.get(DESIGN_DB) - } catch (err) { - // no design doc, make one - designDoc = DesignDoc() - } - const view = { - // if using variables in a map function need to inject them before use - map: `function(doc) { - if (doc.tenantId) { - emit(doc._id.toLowerCase(), doc._id) - } - }`, - } - designDoc.views = { - ...designDoc.views, - [ViewName.PLATFORM_USERS_LOWERCASE]: view, - } - await db.put(designDoc) + await createView(db, viewJs, ViewName.PLATFORM_USERS_LOWERCASE) } ) } @@ -196,7 +133,7 @@ export const queryView = async ( viewName: ViewName, params: PouchDB.Query.Options, db: PouchDB.Database, - CreateFuncByName: any, + createFunc: any, opts?: QueryViewOptions ): Promise => { try { @@ -213,10 +150,9 @@ export const queryView = async ( } } catch (err: any) { if (err != null && err.name === "not_found") { - const createFunc = CreateFuncByName[viewName] await removeDeprecated(db, viewName) await createFunc() - return queryView(viewName, params, db, CreateFuncByName, opts) + return queryView(viewName, params, db, createFunc, opts) } else { throw err } @@ -228,7 +164,7 @@ export const queryPlatformView = async ( params: PouchDB.Query.Options, opts?: QueryViewOptions ): Promise => { - const CreateFuncByName = { + const CreateFuncByName: any = { [ViewName.ACCOUNT_BY_EMAIL]: createAccountEmailView, [ViewName.PLATFORM_USERS_LOWERCASE]: createPlatformUserView, } @@ -236,7 +172,8 @@ export const queryPlatformView = async ( return doWithDB( StaticDatabases.PLATFORM_INFO.name, async (db: PouchDB.Database) => { - return queryView(viewName, params, db, CreateFuncByName, opts) + const createFn = CreateFuncByName[viewName] + return queryView(viewName, params, db, createFn, opts) } ) } @@ -247,7 +184,7 @@ export const queryGlobalView = async ( db?: PouchDB.Database, opts?: QueryViewOptions ): Promise => { - const CreateFuncByName = { + const CreateFuncByName: any = { [ViewName.USER_BY_EMAIL]: createNewUserEmailView, [ViewName.BY_API_KEY]: createApiKeyView, [ViewName.USER_BY_BUILDERS]: createUserBuildersView, @@ -257,5 +194,6 @@ export const queryGlobalView = async ( if (!db) { db = getGlobalDB() as PouchDB.Database } - return queryView(viewName, params, db, CreateFuncByName, opts) + const createFn = CreateFuncByName[viewName] + return queryView(viewName, params, db, createFn, opts) } diff --git a/packages/backend-core/src/events/processors/LoggingProcessor.ts b/packages/backend-core/src/events/processors/LoggingProcessor.ts index a517fba09c..d41a82fbb4 100644 --- a/packages/backend-core/src/events/processors/LoggingProcessor.ts +++ b/packages/backend-core/src/events/processors/LoggingProcessor.ts @@ -23,9 +23,11 @@ export default class LoggingProcessor implements EventProcessor { return } let timestampString = getTimestampString(timestamp) - console.log( - `[audit] [tenant=${identity.tenantId}] [identityType=${identity.type}] [identity=${identity.id}] ${timestampString} ${event} ` - ) + let message = `[audit] [tenant=${identity.tenantId}] [identityType=${identity.type}] [identity=${identity.id}] ${timestampString} ${event} ` + if (env.isDev()) { + message = message + `[debug: [properties=${JSON.stringify(properties)}] ]` + } + console.log(message) } async identify(identity: Identity, timestamp?: string | number) { diff --git a/packages/backend-core/src/events/publishers/group.ts b/packages/backend-core/src/events/publishers/group.ts index d300873725..b4fd0d1469 100644 --- a/packages/backend-core/src/events/publishers/group.ts +++ b/packages/backend-core/src/events/publishers/group.ts @@ -40,9 +40,9 @@ export async function usersAdded(count: number, group: UserGroup) { await publishEvent(Event.USER_GROUP_USERS_ADDED, properties) } -export async function usersDeleted(emails: string[], group: UserGroup) { +export async function usersDeleted(count: number, group: UserGroup) { const properties: GroupUsersDeletedEvent = { - count: emails.length, + count, groupId: group._id as string, } await publishEvent(Event.USER_GROUP_USERS_REMOVED, properties) diff --git a/packages/backend-core/src/events/publishers/license.ts b/packages/backend-core/src/events/publishers/license.ts index 1adc71652e..84472e408f 100644 --- a/packages/backend-core/src/events/publishers/license.ts +++ b/packages/backend-core/src/events/publishers/license.ts @@ -1,27 +1,78 @@ import { publishEvent } from "../events" import { Event, - License, LicenseActivatedEvent, - LicenseDowngradedEvent, - LicenseUpdatedEvent, - LicenseUpgradedEvent, + LicensePlanChangedEvent, + LicenseTierChangedEvent, + PlanType, + Account, + LicensePortalOpenedEvent, + LicenseCheckoutSuccessEvent, + LicenseCheckoutOpenedEvent, + LicensePaymentFailedEvent, + LicensePaymentRecoveredEvent, } from "@budibase/types" -// TODO -export async function updgraded(license: License) { - const properties: LicenseUpgradedEvent = {} - await publishEvent(Event.LICENSE_UPGRADED, properties) +export async function tierChanged(account: Account, from: number, to: number) { + const properties: LicenseTierChangedEvent = { + accountId: account.accountId, + to, + from, + } + await publishEvent(Event.LICENSE_TIER_CHANGED, properties) } -// TODO -export async function downgraded(license: License) { - const properties: LicenseDowngradedEvent = {} - await publishEvent(Event.LICENSE_DOWNGRADED, properties) +export async function planChanged( + account: Account, + from: PlanType, + to: PlanType +) { + const properties: LicensePlanChangedEvent = { + accountId: account.accountId, + to, + from, + } + await publishEvent(Event.LICENSE_PLAN_CHANGED, properties) } -// TODO -export async function activated(license: License) { - const properties: LicenseActivatedEvent = {} +export async function activated(account: Account) { + const properties: LicenseActivatedEvent = { + accountId: account.accountId, + } await publishEvent(Event.LICENSE_ACTIVATED, properties) } + +export async function checkoutOpened(account: Account) { + const properties: LicenseCheckoutOpenedEvent = { + accountId: account.accountId, + } + await publishEvent(Event.LICENSE_CHECKOUT_OPENED, properties) +} + +export async function checkoutSuccess(account: Account) { + const properties: LicenseCheckoutSuccessEvent = { + accountId: account.accountId, + } + await publishEvent(Event.LICENSE_CHECKOUT_SUCCESS, properties) +} + +export async function portalOpened(account: Account) { + const properties: LicensePortalOpenedEvent = { + accountId: account.accountId, + } + await publishEvent(Event.LICENSE_PORTAL_OPENED, properties) +} + +export async function paymentFailed(account: Account) { + const properties: LicensePaymentFailedEvent = { + accountId: account.accountId, + } + await publishEvent(Event.LICENSE_PAYMENT_FAILED, properties) +} + +export async function paymentRecovered(account: Account) { + const properties: LicensePaymentRecoveredEvent = { + accountId: account.accountId, + } + await publishEvent(Event.LICENSE_PAYMENT_RECOVERED, properties) +} diff --git a/packages/backend-core/src/featureFlags/index.js b/packages/backend-core/src/featureFlags/index.js index b328839fda..8a8162d0ba 100644 --- a/packages/backend-core/src/featureFlags/index.js +++ b/packages/backend-core/src/featureFlags/index.js @@ -53,7 +53,7 @@ exports.getTenantFeatureFlags = tenantId => { return flags } -exports.FeatureFlag = { +exports.TenantFeatureFlag = { LICENSING: "LICENSING", GOOGLE_SHEETS: "GOOGLE_SHEETS", USER_GROUPS: "USER_GROUPS", diff --git a/packages/backend-core/src/index.ts b/packages/backend-core/src/index.ts index 2c234bd4b8..83b23b479d 100644 --- a/packages/backend-core/src/index.ts +++ b/packages/backend-core/src/index.ts @@ -18,6 +18,7 @@ import * as logging from "./logging" import pino from "./pino" import * as middleware from "./middleware" import plugins from "./plugin" +import encryption from "./security/encryption" // mimic the outer package exports import * as db from "./pkg/db" @@ -60,6 +61,7 @@ const core = { ...pino, ...errorClasses, middleware, + encryption, } export = core diff --git a/packages/backend-core/src/plugin/utils.js b/packages/backend-core/src/plugin/utils.js index 020fb4484d..ade84bf44a 100644 --- a/packages/backend-core/src/plugin/utils.js +++ b/packages/backend-core/src/plugin/utils.js @@ -75,6 +75,15 @@ function validateDatasource(schema) { }) .unknown(true) .required(), + extra: joi.object().pattern( + joi.string(), + joi.object({ + type: joi.string().required(), + displayName: joi.string().required(), + required: joi.boolean(), + data: joi.object(), + }) + ), }), }) runJoi(validator, schema) diff --git a/packages/backend-core/src/security/roles.js b/packages/backend-core/src/security/roles.js index 983aebf676..33c9123b63 100644 --- a/packages/backend-core/src/security/roles.js +++ b/packages/backend-core/src/security/roles.js @@ -78,7 +78,7 @@ function isBuiltin(role) { */ exports.builtinRoleToNumber = id => { const builtins = exports.getBuiltinRoles() - const MAX = Object.values(BUILTIN_IDS).length + 1 + const MAX = Object.values(builtins).length + 1 if (id === BUILTIN_IDS.ADMIN || id === BUILTIN_IDS.BUILDER) { return MAX } @@ -94,6 +94,22 @@ exports.builtinRoleToNumber = id => { return count } +/** + * Converts any role to a number, but has to be async to get the roles from db. + */ +exports.roleToNumber = async id => { + if (exports.isBuiltin(id)) { + return exports.builtinRoleToNumber(id) + } + const hierarchy = await exports.getUserRoleHierarchy(id) + for (let role of hierarchy) { + if (isBuiltin(role.inherits)) { + return exports.builtinRoleToNumber(role.inherits) + 1 + } + } + return 0 +} + /** * Returns whichever builtin roleID is lower. */ @@ -172,7 +188,7 @@ async function getAllUserRoles(userRoleId) { * to determine if a user can access something that requires a specific role. * @param {string} userRoleId The user's role ID, this can be found in their access token. * @param {object} opts Various options, such as whether to only retrieve the IDs (default true). - * @returns {Promise} returns an ordered array of the roles, with the first being their + * @returns {Promise} returns an ordered array of the roles, with the first being their * highest level of access and the last being the lowest level. */ exports.getUserRoleHierarchy = async (userRoleId, opts = { idOnly: true }) => { diff --git a/packages/backend-core/src/tenancy/tenancy.ts b/packages/backend-core/src/tenancy/tenancy.ts index a100888212..ad5c6b5287 100644 --- a/packages/backend-core/src/tenancy/tenancy.ts +++ b/packages/backend-core/src/tenancy/tenancy.ts @@ -121,7 +121,7 @@ export const getTenantUser = async ( return response } -export const isUserInAppTenant = (appId: string, user: any) => { +export const isUserInAppTenant = (appId: string, user?: any) => { let userTenantId if (user) { userTenantId = user.tenantId || DEFAULT_TENANT_ID diff --git a/packages/backend-core/src/users.ts b/packages/backend-core/src/users.ts index 0793eeb1d9..44f04749c9 100644 --- a/packages/backend-core/src/users.ts +++ b/packages/backend-core/src/users.ts @@ -6,7 +6,24 @@ import { } from "./db/utils" import { queryGlobalView } from "./db/views" import { UNICODE_MAX } from "./db/constants" -import { User } from "@budibase/types" +import { BulkDocsResponse, User } from "@budibase/types" +import { getGlobalDB } from "./context" +import PouchDB from "pouchdb" + +export const bulkGetGlobalUsersById = async (userIds: string[]) => { + const db = getGlobalDB() as PouchDB.Database + return ( + await db.allDocs({ + keys: userIds, + include_docs: true, + }) + ).rows.map(row => row.doc) as User[] +} + +export const bulkUpdateGlobalUsers = async (users: User[]) => { + const db = getGlobalDB() as PouchDB.Database + return (await db.bulkDocs(users)) as BulkDocsResponse +} /** * Given an email address this will use a view to search through diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 8f3c1107e7..bb42e08a67 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": "1.4.17", + "version": "1.4.18-alpha.0", "license": "MPL-2.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", @@ -38,7 +38,7 @@ ], "dependencies": { "@adobe/spectrum-css-workflow-icons": "^1.2.1", - "@budibase/string-templates": "^1.4.17", + "@budibase/string-templates": "1.4.18-alpha.0", "@spectrum-css/actionbutton": "^1.0.1", "@spectrum-css/actiongroup": "^1.0.1", "@spectrum-css/avatar": "^3.0.2", diff --git a/packages/bbui/src/Form/Core/PickerDropdown.svelte b/packages/bbui/src/Form/Core/PickerDropdown.svelte index 28cb2b2a4e..1607876b46 100644 --- a/packages/bbui/src/Form/Core/PickerDropdown.svelte +++ b/packages/bbui/src/Form/Core/PickerDropdown.svelte @@ -9,13 +9,13 @@ import StatusLight from "../../StatusLight/StatusLight.svelte" import Detail from "../../Typography/Detail.svelte" import Search from "./Search.svelte" + import IconAvatar from "../../Icon/IconAvatar.svelte" export let primaryLabel = "" export let primaryValue = null export let id = null export let placeholder = "Choose an option or type" export let disabled = false - export let updateOnChange = true export let error = null export let secondaryOptions = [] export let primaryOptions = [] @@ -204,19 +204,11 @@ })} > {#if primaryOptions[title].getIcon(option)} -
-
- -
-
+ {:else if getPrimaryOptionColour(option, idx)} {/if} - {primaryOptions[title].getLabel(option)} - +
+ +
+ + diff --git a/packages/bbui/src/List/ListItem.svelte b/packages/bbui/src/List/ListItem.svelte index c9e4e397e2..40d3c5541c 100644 --- a/packages/bbui/src/List/ListItem.svelte +++ b/packages/bbui/src/List/ListItem.svelte @@ -1,11 +1,12 @@ - +
Headers @@ -61,7 +61,7 @@
- +
Authentication @@ -73,7 +73,7 @@ - +
Variables diff --git a/packages/builder/src/components/common/DashCard.svelte b/packages/builder/src/components/common/DashCard.svelte index d5d9d2ff37..40c7133c42 100644 --- a/packages/builder/src/components/common/DashCard.svelte +++ b/packages/builder/src/components/common/DashCard.svelte @@ -30,13 +30,14 @@ background: var(--spectrum-alias-background-color-primary); border-radius: var(--border-radius-s); overflow: hidden; - min-height: 150px; + min-height: 170px; } .dash-card-header { padding: var(--spacing-xl) var(--spectrum-global-dimension-static-size-400); border-bottom: 1px solid var(--spectrum-global-color-gray-300); display: flex; justify-content: space-between; + transition: background-color 130ms ease-out; } .dash-card-body { padding: var(--spacing-xl) calc(var(--spacing-xl) * 2); diff --git a/packages/builder/src/components/common/RoleSelect.svelte b/packages/builder/src/components/common/RoleSelect.svelte index a3f75fd4eb..aa39e5cb60 100644 --- a/packages/builder/src/components/common/RoleSelect.svelte +++ b/packages/builder/src/components/common/RoleSelect.svelte @@ -1,13 +1,23 @@ {#if $auth.isAdmin} diff --git a/packages/builder/src/pages/builder/portal/manage/auth/index.svelte b/packages/builder/src/pages/builder/portal/manage/auth/index.svelte index 733d7eee92..dab0bfdd90 100644 --- a/packages/builder/src/pages/builder/portal/manage/auth/index.svelte +++ b/packages/builder/src/pages/builder/portal/manage/auth/index.svelte @@ -311,7 +311,7 @@ {#if providers.google} - +
@@ -350,7 +350,7 @@ {/if} {#if providers.oidc} - +
diff --git a/packages/builder/src/pages/builder/portal/manage/email/index.svelte b/packages/builder/src/pages/builder/portal/manage/email/index.svelte index 812aa5b014..71583222da 100644 --- a/packages/builder/src/pages/builder/portal/manage/email/index.svelte +++ b/packages/builder/src/pages/builder/portal/manage/email/index.svelte @@ -132,7 +132,7 @@ values below and click activate. - + {#if smtpConfig} SMTP @@ -186,7 +186,7 @@ Reset
- + Templates diff --git a/packages/builder/src/pages/builder/portal/manage/groups/[groupId].svelte b/packages/builder/src/pages/builder/portal/manage/groups/[groupId].svelte index 17c16c639b..23cdbff877 100644 --- a/packages/builder/src/pages/builder/portal/manage/groups/[groupId].svelte +++ b/packages/builder/src/pages/builder/portal/manage/groups/[groupId].svelte @@ -5,13 +5,16 @@ Button, Layout, Heading, - Body, Icon, Popover, notifications, List, ListItem, StatusLight, + Divider, + ActionMenu, + MenuItem, + Modal, } from "@budibase/bbui" import UserGroupPicker from "components/settings/UserGroupPicker.svelte" import { createPaginationStore } from "helpers/pagination" @@ -19,91 +22,32 @@ import { onMount } from "svelte" import { RoleUtils } from "@budibase/frontend-core" import { roles } from "stores/backend" + import ConfirmDialog from "components/common/ConfirmDialog.svelte" + import CreateEditGroupModal from "./_components/CreateEditGroupModal.svelte" + import GroupIcon from "./_components/GroupIcon.svelte" export let groupId let popoverAnchor let popover let searchTerm = "" - let selectedUsers = [] let prevSearch = undefined let pageInfo = createPaginationStore() let loaded = false + let editModal + let deleteModal $: page = $pageInfo.page $: fetchUsers(page, searchTerm) $: group = $groups.find(x => x._id === groupId) - - async function addAll() { - selectedUsers = [...selectedUsers, ...filtered.map(u => u._id)] - - let reducedUserObjects = filtered.map(u => { - return { - _id: u._id, - email: u.email, - } - }) - group.users = [...reducedUserObjects, ...group.users] - - await groups.actions.save(group) - - $users.data.forEach(async user => { - let userToEdit = await users.get(user._id) - let userGroups = userToEdit.userGroups || [] - userGroups.push(groupId) - await users.save({ - ...userToEdit, - userGroups, - }) - }) - } - - async function selectUser(id) { - let selectedUser = selectedUsers.includes(id) - if (selectedUser) { - selectedUsers = selectedUsers.filter(id => id !== selectedUser) - let newUsers = group.users.filter(user => user._id !== id) - group.users = newUsers - } else { - let enrichedUser = $users.data - .filter(user => user._id === id) - .map(u => { - return { - _id: u._id, - email: u.email, - } - })[0] - selectedUsers = [...selectedUsers, id] - group.users.push(enrichedUser) + $: filtered = $users.data + $: groupApps = $apps.filter(app => + groups.actions.getGroupAppIds(group).includes(apps.getProdAppID(app.appId)) + ) + $: { + if (loaded && !group?._id) { + $goto("./") } - - await groups.actions.save(group) - - let user = await users.get(id) - - let userGroups = user.userGroups || [] - userGroups.push(groupId) - await users.save({ - ...user, - userGroups, - }) - } - $: filtered = - $users.data?.filter(x => !group?.users.map(y => y._id).includes(x._id)) || - [] - - $: groupApps = $apps.filter(x => group.apps.includes(x.appId)) - async function removeUser(id) { - let newUsers = group.users.filter(user => user._id !== id) - group.users = newUsers - let user = await users.get(id) - - await users.save({ - ...user, - userGroups: [], - }) - - await groups.actions.save(group) } async function fetchUsers(page, search) { @@ -126,11 +70,29 @@ } const getRoleLabel = appId => { - const roleId = group?.roles?.[`app_${appId}`] + const roleId = group?.roles?.[apps.getProdAppID(appId)] const role = $roles.find(x => x._id === roleId) return role?.name || "Custom role" } + async function deleteGroup() { + try { + await groups.actions.delete(group) + notifications.success("User group deleted successfully") + $goto("./") + } catch (error) { + notifications.error(`Failed to delete user group`) + } + } + + async function saveGroup(group) { + try { + await groups.actions.save(group) + } catch (error) { + notifications.error(`Failed to save user group`) + } + } + onMount(async () => { try { await Promise.all([groups.actions.init(), apps.load(), roles.fetch()]) @@ -142,119 +104,137 @@ {#if loaded} - +
- $goto("../groups")} - size="S" - icon="ArrowLeft" - > + $goto("../groups")} icon="ArrowLeft"> Back
-
-
-
-
- + + +
+
+ +
+ {group?.name}
-
- {group?.name} +
+ + + + + editModal.show()}> + Edit + + deleteModal.show()}> + Delete + +
-
- -
- - - -
- - {#if group?.users.length} - {#each group.users as user} - removeUser(user?._id)} - hoverable - size="L" - name="Close" - /> - {/each} - {:else} - - {/if} - -
- Apps -
- Manage apps that this User group has been assigned to -
-
+ - - {#if groupApps.length} - {#each groupApps as app} - -
- +
+ Users +
+ +
+ + user._id)} + list={$users.data} + on:select={e => groups.actions.addUser(groupId, e.detail)} + on:deselect={e => groups.actions.removeUser(groupId, e.detail)} + /> + +
+ + {#if group?.users.length} + {#each group.users as user} + $goto(`../users/${user._id}`)} + hoverable > - {getRoleLabel(app.appId)} -
-
-
- {/each} - {:else} - - {/if} -
+ { + groups.actions.removeUser(groupId, user._id) + e.stopPropagation() + }} + hoverable + size="S" + name="Close" + /> + + {/each} + {:else} + + {/if} + +
+ + + + Apps + + {#if groupApps.length} + {#each groupApps as app} + $goto(`../../overview/${app.devId}`)} + hoverable + > +
+ + {getRoleLabel(app.appId)} + +
+
+ {/each} + {:else} + + {/if} +
+
{/if} - diff --git a/packages/builder/src/pages/builder/portal/manage/groups/_components/GroupAppsTableRenderer.svelte b/packages/builder/src/pages/builder/portal/manage/groups/_components/GroupAppsTableRenderer.svelte new file mode 100644 index 0000000000..51f4d7f77c --- /dev/null +++ b/packages/builder/src/pages/builder/portal/manage/groups/_components/GroupAppsTableRenderer.svelte @@ -0,0 +1,24 @@ + + +
+
+ +
+ {count} +
+ + diff --git a/packages/builder/src/pages/builder/portal/manage/groups/_components/GroupIcon.svelte b/packages/builder/src/pages/builder/portal/manage/groups/_components/GroupIcon.svelte new file mode 100644 index 0000000000..c207501b55 --- /dev/null +++ b/packages/builder/src/pages/builder/portal/manage/groups/_components/GroupIcon.svelte @@ -0,0 +1,8 @@ + + + diff --git a/packages/builder/src/pages/builder/portal/manage/users/_components/NameTableRenderer.svelte b/packages/builder/src/pages/builder/portal/manage/groups/_components/GroupNameTableRenderer.svelte similarity index 50% rename from packages/builder/src/pages/builder/portal/manage/users/_components/NameTableRenderer.svelte rename to packages/builder/src/pages/builder/portal/manage/groups/_components/GroupNameTableRenderer.svelte index a4b65c4d62..e14458d12a 100644 --- a/packages/builder/src/pages/builder/portal/manage/users/_components/NameTableRenderer.svelte +++ b/packages/builder/src/pages/builder/portal/manage/groups/_components/GroupNameTableRenderer.svelte @@ -1,20 +1,13 @@
{#if value} -
- x[0]) - .join("")} - /> -
+ {value} {:else}
-
@@ -26,12 +19,8 @@ display: flex; align-items: center; overflow: hidden; + gap: var(--spacing-m); } - - .spacing { - margin-right: var(--spacing-m); - } - .text { opacity: 0.8; } diff --git a/packages/builder/src/pages/builder/portal/manage/groups/_components/UserGroupsRow.svelte b/packages/builder/src/pages/builder/portal/manage/groups/_components/UserGroupsRow.svelte deleted file mode 100644 index e00123614a..0000000000 --- a/packages/builder/src/pages/builder/portal/manage/groups/_components/UserGroupsRow.svelte +++ /dev/null @@ -1,129 +0,0 @@ - - -
-
-
-
- -
-
-
- {group.name} -
-
-
-
- -
- {parseInt(group?.users?.length) || 0} user{parseInt( - group?.users?.length - ) === 1 - ? "" - : "s"} -
-
-
- - -
- {parseInt(group?.apps?.length) || 0} app{parseInt(group?.apps?.length) === 1 - ? "" - : "s"} -
-
-
-
-
- -
-
- - - - - deleteGroup(group)} icon="Delete" - >Delete - editGroup(group)} icon="Edit">Edit - -
-
-
- - - - - - diff --git a/packages/builder/src/pages/builder/portal/manage/groups/_components/UsersTableRenderer.svelte b/packages/builder/src/pages/builder/portal/manage/groups/_components/UsersTableRenderer.svelte new file mode 100644 index 0000000000..2adc0c82ae --- /dev/null +++ b/packages/builder/src/pages/builder/portal/manage/groups/_components/UsersTableRenderer.svelte @@ -0,0 +1,22 @@ + + +
+
+ +
+ {parseInt(value?.length) || 0} +
+ + diff --git a/packages/builder/src/pages/builder/portal/manage/groups/index.svelte b/packages/builder/src/pages/builder/portal/manage/groups/index.svelte index bb8f18ff13..558e9af8b7 100644 --- a/packages/builder/src/pages/builder/portal/manage/groups/index.svelte +++ b/packages/builder/src/pages/builder/portal/manage/groups/index.svelte @@ -4,16 +4,23 @@ Heading, Body, Button, + ButtonGroup, Modal, Tag, Tags, + Table, + Divider, + Search, notifications, } from "@budibase/bbui" - import { groups, auth } from "stores/portal" + import { groups, auth, licensing, admin } from "stores/portal" import { onMount } from "svelte" import CreateEditGroupModal from "./_components/CreateEditGroupModal.svelte" - import UserGroupsRow from "./_components/UserGroupsRow.svelte" import { cloneDeep } from "lodash/fp" + import GroupAppsTableRenderer from "./_components/GroupAppsTableRenderer.svelte" + import UsersTableRenderer from "./_components/UsersTableRenderer.svelte" + import GroupNameTableRenderer from "./_components/GroupNameTableRenderer.svelte" + import { goto } from "@roxi/routify" const DefaultGroup = { name: "", @@ -23,20 +30,38 @@ apps: [], roles: {}, } - let modal - let group = cloneDeep(DefaultGroup) - async function deleteGroup(group) { - try { - groups.actions.delete(group) - } catch (error) { - notifications.error(`Failed to delete group`) + let modal + let searchString + let group = cloneDeep(DefaultGroup) + let customRenderers = [ + { column: "name", component: GroupNameTableRenderer }, + { column: "users", component: UsersTableRenderer }, + { column: "roles", component: GroupAppsTableRenderer }, + ] + + $: schema = { + name: {}, + users: { sortable: false }, + roles: { sortable: false, displayName: "Apps" }, + } + $: filteredGroups = filterGroups($groups, searchString) + + const filterGroups = (groups, searchString) => { + if (!searchString) { + return groups } + searchString = searchString.toLocaleLowerCase() + return groups?.filter(group => { + return group.name?.toLowerCase().includes(searchString) + }) } async function saveGroup(group) { try { - await groups.actions.save(group) + group = await groups.actions.save(group) + $goto(`./${group._id}`) + notifications.success(`User group created successfully`) } catch (error) { if (error.status === 400) { notifications.error(error.message) @@ -53,62 +78,81 @@ onMount(async () => { try { - if ($auth.groupsEnabled) { + // always load latest + await licensing.init() + if ($licensing.groupsEnabled) { await groups.actions.init() } } catch (error) { - notifications.error("Error getting User groups") + notifications.error("Error getting user groups") } }) - + -
- User groups - {#if !$auth.groupsEnabled} - -
-
- Pro plan -
+ User groups + {#if !$licensing.groupsEnabled} + +
+
+ Pro plan
- - {/if} -
- Easily assign and manage your users access with User Groups - -
- - {#if !$auth.groupsEnabled} - - {/if} -
- - {#if $auth.groupsEnabled && $groups.length} -
- {#each $groups as group} -
-
- {/each} + + {/if} + + Easily assign and manage your users' access with user groups. + {#if !$auth.accountPortalAccess && !$licensing.groupsEnabled && $admin.cloud} + Contact your account holder to upgrade your plan. + {/if} + + + +
+ + {#if $licensing.groupsEnabled} + + + {:else} + + + + {/if} + +
+
- {/if} +
+ $goto(`./${detail._id}`)} + {schema} + data={filteredGroups} + allowEditColumns={false} + allowEditRows={false} + {customRenderers} + /> @@ -116,37 +160,24 @@ diff --git a/packages/builder/src/pages/builder/portal/manage/plugins/index.svelte b/packages/builder/src/pages/builder/portal/manage/plugins/index.svelte index c03232d091..b1f2480c28 100644 --- a/packages/builder/src/pages/builder/portal/manage/plugins/index.svelte +++ b/packages/builder/src/pages/builder/portal/manage/plugins/index.svelte @@ -45,7 +45,7 @@ Plugins - Add your own custom datasources and components + Add your own custom datasources and components. diff --git a/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte b/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte index 8f7b24f1b6..f818595539 100644 --- a/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte +++ b/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte @@ -19,17 +19,17 @@ Modal, notifications, Divider, + Banner, StatusLight, } from "@budibase/bbui" import { onMount } from "svelte" - import { fetchData } from "helpers" - import { users, auth, groups, apps } from "stores/portal" + import { users, auth, groups, apps, licensing } from "stores/portal" import { roles } from "stores/backend" - import { Constants } from "@budibase/frontend-core" import ForceResetPasswordModal from "./_components/ForceResetPasswordModal.svelte" - import { RoleUtils } from "@budibase/frontend-core" import UserGroupPicker from "components/settings/UserGroupPicker.svelte" import DeleteUserModal from "./_components/DeleteUserModal.svelte" + import GroupIcon from "../groups/_components/GroupIcon.svelte" + import { Constants, RoleUtils } from "@budibase/frontend-core" export let userId @@ -38,59 +38,57 @@ let popoverAnchor let searchTerm = "" let popover - let selectedGroups = [] - let allAppList = [] let user let loaded = false - $: fetchUser(userId) - $: fullName = $userFetch?.data?.firstName - ? $userFetch?.data?.firstName + " " + $userFetch?.data?.lastName - : "" - $: nameLabel = getNameLabel($userFetch) + $: fullName = user?.firstName ? user?.firstName + " " + user?.lastName : "" + $: privileged = user?.admin?.global || user?.builder?.global + $: nameLabel = getNameLabel(user) $: initials = getInitials(nameLabel) - $: allAppList = $apps - .filter(x => { - if ($userFetch.data?.roles) { - return Object.keys($userFetch.data.roles).find(y => { - return x.appId === apps.extractAppId(y) - }) - } - }) - .map(app => { - let roles = Object.fromEntries( - Object.entries($userFetch.data.roles).filter(([key]) => { - return apps.extractAppId(key) === app.appId - }) - ) - return { - name: app.name, - devId: app.devId, - icon: app.icon, - roles, - } - }) - // Used for searching through groups in the add group popover - $: filteredGroups = $groups.filter( - group => - selectedGroups && - group?.name?.toLowerCase().includes(searchTerm.toLowerCase()) - ) + $: filteredGroups = getFilteredGroups($groups, searchTerm) + $: availableApps = getAvailableApps($apps, privileged, user?.roles) $: userGroups = $groups.filter(x => { return x.users?.find(y => { return y._id === userId }) }) - $: globalRole = $userFetch?.data?.admin?.global + $: globalRole = user?.admin?.global ? "admin" - : $userFetch?.data?.builder?.global + : user?.builder?.global ? "developer" : "appUser" - const userFetch = fetchData(`/api/global/users/${userId}`) + const getAvailableApps = (appList, privileged, roles) => { + let availableApps = appList.slice() + if (!privileged) { + availableApps = availableApps.filter(x => { + return Object.keys(roles || {}).find(y => { + return x.appId === apps.extractAppId(y) + }) + }) + } + return availableApps.map(app => { + const prodAppId = apps.getProdAppID(app.appId) + console.log(prodAppId) + return { + name: app.name, + devId: app.devId, + icon: app.icon, + role: privileged ? Constants.Roles.ADMIN : roles[prodAppId], + } + }) + } - const getNameLabel = userFetch => { - const { firstName, lastName, email } = userFetch?.data || {} + const getFilteredGroups = (groups, search) => { + if (!search) { + return groups + } + search = search.toLowerCase() + return groups.filter(group => group.name?.toLowerCase().includes(search)) + } + + const getNameLabel = user => { + const { firstName, lastName, email } = user || {} if (!firstName && !lastName) { return email || "" } @@ -122,38 +120,19 @@ return role?.name || "Custom role" } - function getHighestRole(roles) { - let highestRole - let highestRoleNumber = 0 - Object.keys(roles).forEach(role => { - let roleNumber = RoleUtils.getRolePriority(roles[role]) - if (roleNumber > highestRoleNumber) { - highestRoleNumber = roleNumber - highestRole = roles[role] - } - }) - return highestRole - } async function updateUserFirstName(evt) { try { - await users.save({ ...$userFetch?.data, firstName: evt.target.value }) - await userFetch.refresh() + await users.save({ ...user, firstName: evt.target.value }) + await fetchUser() } catch (error) { notifications.error("Error updating user") } } - async function removeGroup(id) { - let updatedGroup = $groups.find(x => x._id === id) - let newUsers = updatedGroup.users.filter(user => user._id !== userId) - updatedGroup.users = newUsers - groups.actions.save(updatedGroup) - } - async function updateUserLastName(evt) { try { - await users.save({ ...$userFetch?.data, lastName: evt.target.value }) - await userFetch.refresh() + await users.save({ ...user, lastName: evt.target.value }) + await fetchUser() } catch (error) { notifications.error("Error updating user") } @@ -169,40 +148,40 @@ } } - async function addGroup(groupId) { - let selectedGroup = selectedGroups.includes(groupId) - let group = $groups.find(group => group._id === groupId) - - if (selectedGroup) { - selectedGroups = selectedGroups.filter(id => id === selectedGroup) - let newUsers = group.users.filter(groupUser => user._id !== groupUser._id) - group.users = newUsers - } else { - selectedGroups = [...selectedGroups, groupId] - group.users.push(user) + async function fetchUser() { + user = await users.get(userId) + if (!user?._id) { + $goto("./") } - - await groups.actions.save(group) - } - - async function fetchUser(userId) { - let userPromise = users.get(userId) - user = await userPromise } async function toggleFlags(detail) { try { - await users.save({ ...$userFetch?.data, ...detail }) - await userFetch.refresh() + await users.save({ ...user, ...detail }) + await fetchUser() } catch (error) { notifications.error("Error updating user") } } - function addAll() {} + const addGroup = async groupId => { + await groups.actions.addUser(groupId, userId) + await fetchUser() + } + + const removeGroup = async groupId => { + await groups.actions.removeUser(groupId, userId) + await fetchUser() + } + onMount(async () => { try { - await Promise.all([groups.actions.init(), apps.load(), roles.fetch()]) + await Promise.all([ + fetchUser(), + groups.actions.init(), + apps.load(), + roles.fetch(), + ]) loaded = true } catch (error) { notifications.error("Error getting user groups") @@ -225,13 +204,13 @@
{nameLabel} - {#if nameLabel !== $userFetch?.data?.email} - {$userFetch?.data?.email} + {#if nameLabel !== user?.email} + {user?.email} {/if}
- {#if userId !== $auth.user._id} + {#if userId !== $auth.user?._id}
@@ -247,27 +226,21 @@
{/if} - + Details
- +
- +
- +
{#if userId !== $auth.user._id} @@ -284,7 +257,7 @@ - {#if $auth.groupsEnabled} + {#if $licensing.groupsEnabled}
@@ -301,13 +274,14 @@
addGroup(e.detail)} + on:deselect={e => removeGroup(e.detail)} + iconComponent={GroupIcon} + extractIconProps={item => ({ group: item, size: "S" })} />
@@ -322,7 +296,10 @@ on:click={() => $goto(`../groups/${group._id}`)} > { + removeGroup(group._id) + e.stopPropagation() + }} hoverable size="S" name="Close" @@ -330,7 +307,7 @@ {/each} {:else} - + {/if}
@@ -339,27 +316,28 @@ Apps - {#if allAppList.length} - {#each allAppList as app} + {#if privileged} + + This user's role grants admin access to all apps + + {:else if availableApps.length} + {#each availableApps as app} $goto(`../../overview/${app.devId}`)} >
- - {getRoleLabel(getHighestRole(app.roles))} + + {getRoleLabel(app.role)}
{/each} {:else} - + {/if}
@@ -367,13 +345,10 @@ {/if} - + - + diff --git a/packages/builder/src/pages/builder/portal/settings/usage.svelte b/packages/builder/src/pages/builder/portal/settings/usage.svelte index f2809452fd..75ceccc0a3 100644 --- a/packages/builder/src/pages/builder/portal/settings/usage.svelte +++ b/packages/builder/src/pages/builder/portal/settings/usage.svelte @@ -147,7 +147,8 @@ const init = async () => { try { - await licensing.getQuotaUsage() + // always load latest + await licensing.init() } catch (e) { console.error(e) notifications.error(e) @@ -175,18 +176,18 @@ {#if loaded} - - + + Usage - Get information about your current usage within Budibase. + + Get information about your current usage within Budibase. {#if accountPortalAccess} To upgrade your plan and usage limits visit your Account {:else} - To upgrade your plan and usage limits contact your account holder + To upgrade your plan and usage limits contact your account holder. {/if} diff --git a/packages/builder/src/stores/portal/apps.js b/packages/builder/src/stores/portal/apps.js index 6323046eef..41fdc232b7 100644 --- a/packages/builder/src/stores/portal/apps.js +++ b/packages/builder/src/stores/portal/apps.js @@ -8,14 +8,21 @@ const extractAppId = id => { } const getProdAppID = appId => { - if (!appId || !appId.startsWith("app_dev")) { + if (!appId) { return appId } - // split to take off the app_dev element, then join it together incase any other app_ exist - const split = appId.split("app_dev") - split.shift() - const rest = split.join("app_dev") - return `${"app"}${rest}` + let rest, + separator = "" + if (appId.startsWith("app_dev")) { + // split to take off the app_dev element, then join it together incase any other app_ exist + const split = appId.split("app_dev") + split.shift() + rest = split.join("app_dev") + } else if (!appId.startsWith("app")) { + rest = appId + separator = "_" + } + return `app${separator}${rest}` } export function createAppStore() { diff --git a/packages/builder/src/stores/portal/auth.js b/packages/builder/src/stores/portal/auth.js index 8ac19ab785..31b4533738 100644 --- a/packages/builder/src/stores/portal/auth.js +++ b/packages/builder/src/stores/portal/auth.js @@ -2,23 +2,20 @@ import { derived, writable, get } from "svelte/store" import { API } from "api" import { admin } from "stores/portal" import analytics from "analytics" -import { FEATURE_FLAGS } from "helpers/featureFlags" -import { Constants } from "@budibase/frontend-core" export function createAuthStore() { const auth = writable({ user: null, + accountPortalAccess: false, tenantId: "default", tenantSet: false, loaded: false, postLogout: false, - groupsEnabled: false, }) const store = derived(auth, $store => { let initials = null let isAdmin = false let isBuilder = false - let groupsEnabled = false if ($store.user) { const user = $store.user if (user.firstName) { @@ -33,12 +30,10 @@ export function createAuthStore() { } isAdmin = !!user.admin?.global isBuilder = !!user.builder?.global - groupsEnabled = - user?.license.features.includes(Constants.Features.USER_GROUPS) && - user?.featureFlags.includes(FEATURE_FLAGS.USER_GROUPS) } return { user: $store.user, + accountPortalAccess: $store.accountPortalAccess, tenantId: $store.tenantId, tenantSet: $store.tenantSet, loaded: $store.loaded, @@ -46,7 +41,6 @@ export function createAuthStore() { initials, isAdmin, isBuilder, - groupsEnabled, } }) @@ -54,6 +48,7 @@ export function createAuthStore() { auth.update(store => { store.loaded = true store.user = user + store.accountPortalAccess = user?.accountPortalAccess if (user) { store.tenantId = user.tenantId || "default" store.tenantSet = true diff --git a/packages/builder/src/stores/portal/groups.js b/packages/builder/src/stores/portal/groups.js index ca814ac057..eda3961e2b 100644 --- a/packages/builder/src/stores/portal/groups.js +++ b/packages/builder/src/stores/portal/groups.js @@ -1,36 +1,45 @@ import { writable, get } from "svelte/store" import { API } from "api" -import { auth } from "stores/portal" -import { Constants } from "@budibase/frontend-core" +import { licensing } from "stores/portal" export function createGroupsStore() { const store = writable([]) + const updateStore = group => { + store.update(state => { + const currentIdx = state.findIndex(gr => gr._id === group._id) + if (currentIdx >= 0) { + state.splice(currentIdx, 1, group) + } else { + state.push(group) + } + return state + }) + } + + const getGroup = async groupId => { + const group = await API.getGroup(groupId) + updateStore(group) + } + const actions = { init: async () => { - // only init if these is a groups license, just to be sure but the feature will be blocked + // only init if there is a groups license, just to be sure but the feature will be blocked // on the backend anyway - if ( - get(auth).user.license.features.includes(Constants.Features.USER_GROUPS) - ) { - const users = await API.getGroups() - store.set(users) + if (get(licensing).groupsEnabled) { + const groups = await API.getGroups() + store.set(groups) } }, + get: getGroup, + save: async group => { const response = await API.saveGroup(group) group._id = response._id group._rev = response._rev - store.update(state => { - const currentIdx = state.findIndex(gr => gr._id === response._id) - if (currentIdx >= 0) { - state.splice(currentIdx, 1, group) - } else { - state.push(group) - } - return state - }) + updateStore(group) + return group }, delete: async group => { @@ -43,6 +52,34 @@ export function createGroupsStore() { return state }) }, + + addUser: async (groupId, userId) => { + await API.addUsersToGroup(groupId, userId) + // refresh the group enrichment + await getGroup(groupId) + }, + + removeUser: async (groupId, userId) => { + await API.removeUsersFromGroup(groupId, userId) + // refresh the group enrichment + await getGroup(groupId) + }, + + addApp: async (groupId, appId, roleId) => { + await API.addAppsToGroup(groupId, [{ appId, roleId }]) + // refresh the group roles + await getGroup(groupId) + }, + + removeApp: async (groupId, appId) => { + await API.removeAppsFromGroup(groupId, [{ appId }]) + // refresh the group roles + await getGroup(groupId) + }, + + getGroupAppIds: group => { + return Object.keys(group?.roles || {}) + }, } return { diff --git a/packages/builder/src/stores/portal/licensing.js b/packages/builder/src/stores/portal/licensing.js index e2b4570302..179dac9689 100644 --- a/packages/builder/src/stores/portal/licensing.js +++ b/packages/builder/src/stores/portal/licensing.js @@ -1,14 +1,31 @@ import { writable, get } from "svelte/store" import { API } from "api" -import { auth } from "stores/portal" +import { auth, admin } from "stores/portal" import { Constants } from "@budibase/frontend-core" import { StripeStatus } from "components/portal/licensing/constants" -import { FEATURE_FLAGS, isEnabled } from "../../helpers/featureFlags" +import { TENANT_FEATURE_FLAGS, isEnabled } from "helpers/featureFlags" export const createLicensingStore = () => { const DEFAULT = { - plans: {}, - usageMetrics: {}, + // navigation + goToUpgradePage: () => {}, + // the top level license + license: undefined, + isFreePlan: true, + // features + groupsEnabled: false, + // the currently used quotas from the db + quotaUsage: undefined, + // derived quota metrics for percentages used + usageMetrics: undefined, + // quota reset + quotaResetDaysRemaining: undefined, + quotaResetDate: undefined, + // failed payments + accountPastDue: undefined, + pastDueEndDate: undefined, + pastDueDaysRemaining: undefined, + accountDowngraded: undefined, } const oneDayInMilliseconds = 86400000 @@ -16,10 +33,39 @@ export const createLicensingStore = () => { const actions = { init: async () => { - await actions.getQuotaUsage() - await actions.getUsageMetrics() + actions.setNavigation() + actions.setLicense() + await actions.setQuotaUsage() + actions.setUsageMetrics() }, - getQuotaUsage: async () => { + setNavigation: () => { + const upgradeUrl = `${get(admin).accountPortalUrl}/portal/upgrade` + const goToUpgradePage = () => { + window.location.href = upgradeUrl + } + store.update(state => { + return { + ...state, + goToUpgradePage, + } + }) + }, + setLicense: () => { + const license = get(auth).user.license + const isFreePlan = license?.plan.type === Constants.PlanType.FREE + const groupsEnabled = license.features.includes( + Constants.Features.USER_GROUPS + ) + store.update(state => { + return { + ...state, + license, + isFreePlan, + groupsEnabled, + } + }) + }, + setQuotaUsage: async () => { const quotaUsage = await API.getQuotaUsage() store.update(state => { return { @@ -28,8 +74,8 @@ export const createLicensingStore = () => { } }) }, - getUsageMetrics: async () => { - if (isEnabled(FEATURE_FLAGS.LICENSING)) { + setUsageMetrics: () => { + if (isEnabled(TENANT_FEATURE_FLAGS.LICENSING)) { const quota = get(store).quotaUsage const license = get(auth).user.license const now = new Date() @@ -41,7 +87,7 @@ export const createLicensingStore = () => { return keys.reduce((acc, key) => { const quotaLimit = license[key].value const quotaUsed = (quota[key] / quotaLimit) * 100 - acc[key] = quotaLimit > -1 ? Math.round(quotaUsed) : -1 + acc[key] = quotaLimit > -1 ? Math.floor(quotaUsed) : -1 return acc }, {}) } @@ -97,9 +143,6 @@ export const createLicensingStore = () => { accountPastDue: pastDueAtMilliseconds != null, pastDueEndDate, pastDueDaysRemaining, - isFreePlan: () => { - return license?.plan.type === Constants.PlanType.FREE - }, } }) } diff --git a/packages/cli/package.json b/packages/cli/package.json index 753e90fd6b..74dac563e2 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/cli", - "version": "1.4.17", + "version": "1.4.18-alpha.0", "description": "Budibase CLI, for developers, self hosting and migrations.", "main": "src/index.js", "bin": { @@ -26,9 +26,9 @@ "outputPath": "build" }, "dependencies": { - "@budibase/backend-core": "^1.4.17", - "@budibase/string-templates": "^1.4.17", - "@budibase/types": "^1.4.17", + "@budibase/backend-core": "1.4.18-alpha.0", + "@budibase/string-templates": "1.4.18-alpha.0", + "@budibase/types": "1.4.18-alpha.0", "axios": "0.21.2", "chalk": "4.1.0", "cli-progress": "3.11.2", diff --git a/packages/cli/yarn.lock b/packages/cli/yarn.lock index 1436b14f46..547e9fd3e2 100644 --- a/packages/cli/yarn.lock +++ b/packages/cli/yarn.lock @@ -43,84 +43,6 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" -"@budibase/backend-core@^1.4.6": - version "1.4.6" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.4.6.tgz#16428077136c8dc50d08807db037f3c46809ff36" - integrity sha512-U6c0LGf7aT5m5KhS2NMsesq5dEo4qNabUdjZ82Zk1SI0ZmtfHXDPW7pmtpNXQbVSFOQ1ZfZOSuF6FK0aCPZDKQ== - dependencies: - "@budibase/types" "^1.4.6" - "@shopify/jest-koa-mocks" "5.0.1" - "@techpass/passport-openidconnect" "0.3.2" - aws-sdk "2.1030.0" - bcrypt "5.0.1" - bcryptjs "2.4.3" - dotenv "16.0.1" - emitter-listener "1.1.2" - ioredis "4.28.0" - joi "17.6.0" - jsonwebtoken "8.5.1" - koa-passport "4.1.4" - lodash "4.17.21" - lodash.isarguments "3.1.0" - node-fetch "2.6.7" - passport-google-auth "1.0.2" - passport-google-oauth "2.0.0" - passport-jwt "4.0.0" - passport-local "1.0.0" - passport-oauth2-refresh "^2.1.0" - posthog-node "1.3.0" - pouchdb "7.3.0" - pouchdb-find "7.2.2" - pouchdb-replication-stream "1.2.9" - redlock "4.2.0" - sanitize-s3-objectkey "0.0.1" - semver "7.3.7" - tar-fs "2.1.1" - uuid "8.3.2" - zlib "1.0.5" - -"@budibase/handlebars-helpers@^0.11.8": - version "0.11.8" - resolved "https://registry.yarnpkg.com/@budibase/handlebars-helpers/-/handlebars-helpers-0.11.8.tgz#6953d29673a8c5c407e096c0a84890465c7ce841" - integrity sha512-ggWJUt0GqsHFAEup5tlWlcrmYML57nKhpNGGLzVsqXVYN8eVmf3xluYmmMe7fDYhQH0leSprrdEXmsdFQF3HAQ== - dependencies: - array-sort "^1.0.0" - define-property "^2.0.2" - extend-shallow "^3.0.2" - for-in "^1.0.2" - get-object "^0.2.0" - get-value "^3.0.1" - handlebars "^4.7.7" - handlebars-utils "^1.0.6" - has-value "^2.0.2" - helper-md "^0.2.2" - html-tag "^2.0.0" - is-even "^1.0.0" - is-glob "^4.0.1" - kind-of "^6.0.3" - micromatch "^3.1.5" - relative "^3.0.2" - striptags "^3.1.1" - to-gfm-code-block "^0.1.1" - year "^0.2.1" - -"@budibase/string-templates@^1.4.6": - version "1.4.6" - resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-1.4.6.tgz#0e4ad2430b684b018962cad471638c85689ed51a" - integrity sha512-6ipioRW7C0LQuV1pAQMtpcF4NGXKZsnyNEi+9u+2zXc9ggR4LmUgCqeT3nJm1w4AmAxW3GU6Fz3+91QXMwDMKA== - dependencies: - "@budibase/handlebars-helpers" "^0.11.8" - dayjs "^1.10.4" - handlebars "^4.7.6" - handlebars-utils "^1.0.6" - lodash "^4.17.20" - vm2 "^3.9.4" - -"@budibase/types@^1.4.6": - version "1.4.6" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-1.4.6.tgz#57cf91a47b9b55f56ae68a39194f1a737b6f737c" - integrity sha512-KUIj6S5WoAHjueMBND9WeEuQGqSOJy6FApem/Ml3ro9JbdedOjBvUT3XALtLELcxBgeMmbgDO1UvdaFC6RnXZw== - "@eslint/eslintrc@^0.4.3": version "0.4.3" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" @@ -162,21 +84,6 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== -"@mapbox/node-pre-gyp@^1.0.0": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c" - integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA== - dependencies: - detect-libc "^2.0.0" - https-proxy-agent "^5.0.0" - make-dir "^3.1.0" - node-fetch "^2.6.7" - nopt "^5.0.0" - npmlog "^5.0.1" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.11" - "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -198,14 +105,6 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@shopify/jest-koa-mocks@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@shopify/jest-koa-mocks/-/jest-koa-mocks-5.0.1.tgz#fba490b6b7985fbb571eb9974897d396a3642e94" - integrity sha512-4YskS9q8+TEHNoyopmuoy2XyhInyqeOl7CF5ShJs19sm6m0EA/jGGvgf/osv2PeTfuf42/L2G9CzWUSg49yTSg== - dependencies: - koa "^2.13.4" - node-mocks-http "^1.11.0" - "@sideway/address@^4.1.3": version "4.1.4" resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" @@ -228,22 +127,6 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== -"@techpass/passport-openidconnect@0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@techpass/passport-openidconnect/-/passport-openidconnect-0.3.2.tgz#f8fd5d97256286665dbf26dac92431f977ab1e63" - integrity sha512-fnCtEiexXSHA029B//hJcCJlLJrT3lhpNCyA0rnz58Qttz0BLGCVv6yMT8HmOnGThH6vcDOVwdgKM3kbCQtEhw== - dependencies: - base64url "^3.0.1" - oauth "^0.9.15" - passport-strategy "^1.0.0" - request "^2.88.0" - webfinger "^0.4.2" - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - abort-controller@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -273,34 +156,16 @@ abstract-leveldown@~6.2.1, abstract-leveldown@~6.2.3: level-supports "~1.0.0" xtend "~4.0.0" -accepts@^1.3.5, accepts@^1.3.7: - version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - acorn-jsx@^5.3.1: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn-walk@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - acorn@^7.4.0: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.7.0: - version "8.8.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" - integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== - agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -308,7 +173,7 @@ agent-base@6: dependencies: debug "4" -ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: +ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -369,11 +234,6 @@ aproba@^1.0.3: resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== -"aproba@^1.0.3 || ^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" - integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== - archive-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/archive-type/-/archive-type-4.0.0.tgz#f92e72233056dfc6969472749c267bdb046b1d70" @@ -381,14 +241,6 @@ archive-type@^4.0.0: dependencies: file-type "^4.2.0" -are-we-there-yet@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" - integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - are-we-there-yet@~1.1.2: version "1.1.7" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" @@ -397,7 +249,7 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" -argparse@^1.0.10, argparse@^1.0.7: +argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== @@ -409,21 +261,6 @@ argsarray@0.0.1: resolved "https://registry.yarnpkg.com/argsarray/-/argsarray-0.0.1.tgz#6e7207b4ecdb39b0af88303fa5ae22bda8df61cb" integrity sha512-u96dg2GcAKtpTrBdDoFIM7PjcBA+6rSP0OR94MOReNRyUECL6MtQt5XXmRr4qrftYaef9+l5hcpO5te7sML1Cg== -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== - array-back@^3.0.1, array-back@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" @@ -439,15 +276,6 @@ array-back@^6.2.0, array-back@^6.2.2: resolved "https://registry.yarnpkg.com/array-back/-/array-back-6.2.2.tgz#f567d99e9af88a6d3d2f9dfcc21db6f9ba9fd157" integrity sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw== -array-sort@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-sort/-/array-sort-1.0.0.tgz#e4c05356453f56f53512a7d1d6123f2c54c0a88a" - integrity sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg== - dependencies: - default-compare "^1.0.0" - get-value "^2.0.6" - kind-of "^5.0.2" - array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -458,87 +286,16 @@ array-uniq@1.0.2: resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.2.tgz#5fcc373920775723cfd64d65c64bef53bf9eba6d" integrity sha512-GVYjmpL05al4dNlKJm53mKE4w9OOLiuVHWorsIA3YVz+Hu0hcn6PtE3Ydl0EqU7v+7ABC4mjjWsnLUxbpno+CA== -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== - -asn1@~0.2.3: - version "0.2.6" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" - integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== - astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== -async@~2.1.4: - version "2.1.5" - resolved "https://registry.yarnpkg.com/async/-/async-2.1.5.tgz#e587c68580994ac67fc56ff86d3ac56bdbe810bc" - integrity sha512-+g/Ncjbx0JSq2Mk03WQkyKvNh5q9Qvyo/RIqIqnmC5feJY70PNl2ESwZU2BhAB+AZPkHNzzyC2Dq2AS5VnTKhQ== - dependencies: - lodash "^4.14.0" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - at-least-node@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -autolinker@~0.28.0: - version "0.28.1" - resolved "https://registry.yarnpkg.com/autolinker/-/autolinker-0.28.1.tgz#0652b491881879f0775dace0cdca3233942a4e47" - integrity sha512-zQAFO1Dlsn69eXaO6+7YZc+v84aquQKbwpzCE3L0stj56ERn9hutFxPopViLjo9G+rWwjozRhgS5KJ25Xy19cQ== - dependencies: - gulp-header "^1.7.1" - -aws-sdk@2.1030.0: - version "2.1030.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1030.0.tgz#24a856af3d2b8b37c14a8f59974993661c66fd82" - integrity sha512-to0STOb8DsSGuSsUb/WCbg/UFnMGfIYavnJH5ZlRCHzvCFjTyR+vfE8ku+qIZvfFM4+5MNTQC/Oxfun2X/TuyA== - dependencies: - buffer "4.9.2" - events "1.1.1" - ieee754 "1.1.13" - jmespath "0.15.0" - querystring "0.2.0" - sax "1.2.1" - url "0.10.3" - uuid "3.3.2" - xml2js "0.4.19" - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - axios-retry@^3.1.9: version "3.3.1" resolved "https://registry.yarnpkg.com/axios-retry/-/axios-retry-3.3.1.tgz#47624646138aedefbad2ac32f226f4ee94b6dcab" @@ -554,13 +311,6 @@ axios@0.21.2: dependencies: follow-redirects "^1.14.0" -axios@0.24.0: - version "0.24.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6" - integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA== - dependencies: - follow-redirects "^1.14.4" - axios@^0.21.1: version "0.21.4" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" @@ -573,49 +323,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-js@^1.0.2, base64-js@^1.3.1: +base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -base64url@3.x.x, base64url@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d" - integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A== - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== - dependencies: - tweetnacl "^0.14.3" - -bcrypt@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/bcrypt/-/bcrypt-5.0.1.tgz#f1a2c20f208e2ccdceea4433df0c8b2c54ecdf71" - integrity sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw== - dependencies: - "@mapbox/node-pre-gyp" "^1.0.0" - node-addon-api "^3.1.0" - -bcryptjs@2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" - integrity sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ== - bl@^1.0.0: version "1.2.3" resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7" @@ -633,11 +345,6 @@ bl@^4.0.3: inherits "^2.0.4" readable-stream "^3.4.0" -bluebird@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -646,22 +353,6 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - braces@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -687,35 +378,16 @@ buffer-crc32@~0.2.3: resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== -buffer-equal-constant-time@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" - integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== - buffer-fill@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== -buffer-from@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - buffer-from@1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer@4.9.2: - version "4.9.2" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" - integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - buffer@^5.2.1, buffer@^5.5.0, buffer@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" @@ -724,29 +396,6 @@ buffer@^5.2.1, buffer@^5.5.0, buffer@^5.6.0: base64-js "^1.3.1" ieee754 "^1.1.13" -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -cache-content-type@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-content-type/-/cache-content-type-1.0.1.tgz#035cde2b08ee2129f4a8315ea8f00a00dba1453c" - integrity sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA== - dependencies: - mime-types "^2.1.18" - ylru "^1.2.0" - cacheable-request@^2.1.1: version "2.1.4" resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" @@ -765,11 +414,6 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== - chalk@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" @@ -815,16 +459,6 @@ chownr@^2.0.0: resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - cli-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" @@ -865,29 +499,11 @@ clone-response@1.0.2: dependencies: mimic-response "^1.0.0" -cluster-key-slot@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d" - integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw== - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== - code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -912,18 +528,6 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-support@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - command-line-args@^5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" @@ -954,11 +558,6 @@ commander@^2.8.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - component-type@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-type/-/component-type-1.2.1.tgz#8a47901700238e4fc32269771230226f24b415a9" @@ -969,43 +568,18 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -concat-with-sourcemaps@*: - version "1.1.0" - resolved "https://registry.yarnpkg.com/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz#d4ea93f05ae25790951b99e7b3b09e3908a4082e" - integrity sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg== - dependencies: - source-map "^0.6.1" - -console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control-strings@~1.1.0: +console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== -content-disposition@^0.5.2, content-disposition@^0.5.3, content-disposition@~0.5.2: +content-disposition@^0.5.2: version "0.5.4" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== dependencies: safe-buffer "5.2.1" -content-type@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - -cookies@~0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.8.0.tgz#1293ce4b391740a8406e3c9870e828c4b54f3f90" - integrity sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow== - dependencies: - depd "~2.0.0" - keygrip "~1.1.0" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== - copyfiles@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.4.1.tgz#d2dcff60aaad1015f09d0b66e7f0f1c5cd3c5da5" @@ -1019,11 +593,6 @@ copyfiles@^2.4.1: untildify "^4.0.0" yargs "^16.1.0" -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== - core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" @@ -1048,32 +617,13 @@ current-module-paths@^1.1.0: resolved "https://registry.yarnpkg.com/current-module-paths/-/current-module-paths-1.1.0.tgz#5d5bf214281d80aea264e642f028e672098238f6" integrity sha512-HGhLUszcgprjKmzvQoCQda8iEWsQn3sWVzPdttyJVR5cjfVDYcoyozQA5D1YXgab9v84SPMpSuD+YrPX6i1IMQ== -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== - dependencies: - assert-plus "^1.0.0" - -dayjs@^1.10.4: - version "1.11.5" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.5.tgz#00e8cc627f231f9499c19b38af49f56dc0ac5e93" - integrity sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA== - -debug@4, debug@^4.0.1, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: +debug@4, debug@^4.0.1, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -debug@^2.2.0, debug@^2.3.3: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -1146,11 +696,6 @@ decompress@^4.2.1: pify "^2.3.0" strip-dirs "^2.0.0" -deep-equal@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" - integrity sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw== - deep-extend@^0.6.0, deep-extend@~0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -1161,13 +706,6 @@ deep-is@^0.1.3, deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -default-compare@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f" - integrity sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ== - dependencies: - kind-of "^5.0.2" - deferred-leveldown@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz#27a997ad95408b61161aa69bd489b86c71b78058" @@ -1176,68 +714,16 @@ deferred-leveldown@~5.3.0: abstract-leveldown "~6.2.1" inherits "^2.0.3" -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== -denque@^1.1.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.1.tgz#07f670e29c9a78f8faecb2566a1e2c11929c5cbf" - integrity sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw== - -depd@^1.1.0, depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - -depd@^2.0.0, depd@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -destroy@^1.0.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - detect-libc@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg== -detect-libc@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" - integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== - dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -1289,43 +775,11 @@ duplexer3@^0.1.4: resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA== -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -ecdsa-sig-formatter@1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" - integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== - dependencies: - safe-buffer "^5.0.1" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - -emitter-listener@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/emitter-listener/-/emitter-listener-1.1.2.tgz#56b140e8f6992375b3d7cb2cab1cc7432d9632e8" - integrity sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ== - dependencies: - shimmer "^1.2.0" - emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -encodeurl@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - encoding-down@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-6.3.0.tgz#b1c4eb0e1728c146ecaef8e32963c549e76d082b" @@ -1357,11 +811,6 @@ enquirer@^2.3.5: dependencies: ansi-colors "^4.1.1" -ent@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" - integrity sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA== - errno@~0.1.1: version "0.1.8" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" @@ -1374,11 +823,6 @@ escalade@^3.1.1: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== -escape-html@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -1520,24 +964,6 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -events@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" - integrity sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw== - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - expand-template@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" @@ -1558,26 +984,6 @@ ext-name@^5.0.0: ext-list "^2.0.0" sort-keys-length "^1.0.0" -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -1587,30 +993,6 @@ external-editor@^3.0.3: iconv-lite "^0.4.24" tmp "^0.0.33" -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== - -extsprintf@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" - integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== - fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -1656,13 +1038,6 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" -fetch-cookie@0.10.1: - version "0.10.1" - resolved "https://registry.yarnpkg.com/fetch-cookie/-/fetch-cookie-0.10.1.tgz#5ea88f3d36950543c87997c27ae2aeafb4b5c4d4" - integrity sha512-beB+VEd4cNeVG1PY+ee74+PkuCQnik78pgLi5Ah/7qdUfov8IctU0vLUbBT8/10Ma5GMBeI4wtxhGrEfKNYs2g== - dependencies: - tough-cookie "^2.3.3 || ^3.0.1 || ^4.0.0" - fetch-cookie@0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/fetch-cookie/-/fetch-cookie-0.11.0.tgz#e046d2abadd0ded5804ce7e2cae06d4331c15407" @@ -1731,16 +1106,6 @@ filenamify@^3.0.0: strip-outer "^1.0.0" trim-repeated "^1.0.0" -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -1773,42 +1138,6 @@ follow-redirects@^1.14.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== -follow-redirects@^1.14.4: - version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== - dependencies: - map-cache "^0.2.2" - -fresh@^0.5.2, fresh@~0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - from2@^2.1.1, from2@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" @@ -1822,11 +1151,6 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-exists-sync@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" - integrity sha512-cR/vflFyPZtrN6b38ZyWxpWdhlXrzZEBawlpBQMq7033xVY7/kg0GDMBK5jg8lDYQckdJ5x/YC88lM3C7VMsLg== - fs-extra@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" @@ -1859,21 +1183,6 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== -gauge@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" - integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.2" - console-control-strings "^1.0.0" - has-unicode "^2.0.1" - object-assign "^4.1.1" - signal-exit "^3.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.2" - gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -1893,14 +1202,6 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-object@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/get-object/-/get-object-0.2.0.tgz#d92ff7d5190c64530cda0543dac63a3d47fe8c0c" - integrity sha512-7P6y6k6EzEFmO/XyUyFlXm1YLJy9xeA1x/grNV8276abX5GuwUtYgKFkRFkLixw4hf4Pz9q2vgv/8Ar42R0HuQ== - dependencies: - is-number "^2.0.2" - isobject "^0.2.0" - get-stream@3.0.0, get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -1921,25 +1222,6 @@ get-stream@^4.1.0: dependencies: pump "^3.0.0" -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== - -get-value@^3.0.0, get-value@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-3.0.1.tgz#5efd2a157f1d6a516d7524e124ac52d0a39ef5a8" - integrity sha512-mKZj9JLQrwMBtj5wxi6MH8Z5eSKaERpAwjg43dPtlGI1ZVEgH/qC7T8/6R2OBSUA+zzHBZgICsVJaEIV2tKTDA== - dependencies: - isobject "^3.0.1" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== - dependencies: - assert-plus "^1.0.0" - github-from-package@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" @@ -1990,32 +1272,6 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" -google-auth-library@~0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-0.10.0.tgz#6e15babee85fd1dd14d8d128a295b6838d52136e" - integrity sha512-KM54Y9GhdAzfXUHmWEoYmaOykSLuMG7W4HvVLYqyogxOyE6px8oSS8W13ngqW0oDGZ915GFW3V6OM6+qcdvPOA== - dependencies: - gtoken "^1.2.1" - jws "^3.1.4" - lodash.noop "^3.0.1" - request "^2.74.0" - -google-p12-pem@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-0.1.2.tgz#33c46ab021aa734fa0332b3960a9a3ffcb2f3177" - integrity sha512-puhMlJ2+E/rgvxWaqgN/nC7x623OAE8MR9vBUqxF0inCE7HoVfCHvTeQ9+BR+rj9KM0fIg6XV6tmbt7XHHssoQ== - dependencies: - node-forge "^0.7.1" - -googleapis@^16.0.0: - version "16.1.0" - resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-16.1.0.tgz#0f19f2d70572d918881a0f626e3b1a2fa8629576" - integrity sha512-5czmF7xkIlJKc1+/+5tltrI1skoR3HKtkDOld9rk+DOucTpZRjOhCoJzoSjxB3M8rP2tEb1VIr1TPyzR3V2PUQ== - dependencies: - async "~2.1.4" - google-auth-library "~0.10.0" - string-template "~1.0.0" - got@^8.3.1: version "8.3.2" resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" @@ -2044,58 +1300,6 @@ graceful-fs@^4.1.10, graceful-fs@^4.1.6, graceful-fs@^4.2.0: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== -gtoken@^1.2.1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-1.2.3.tgz#5509571b8afd4322e124cf66cf68115284c476d8" - integrity sha512-wQAJflfoqSgMWrSBk9Fg86q+sd6s7y6uJhIvvIPz++RElGlMtEqsdAR2oWwZ/WTEtp7P9xFbJRrT976oRgzJ/w== - dependencies: - google-p12-pem "^0.1.0" - jws "^3.0.0" - mime "^1.4.1" - request "^2.72.0" - -gulp-header@^1.7.1: - version "1.8.12" - resolved "https://registry.yarnpkg.com/gulp-header/-/gulp-header-1.8.12.tgz#ad306be0066599127281c4f8786660e705080a84" - integrity sha512-lh9HLdb53sC7XIZOYzTXM4lFuXElv3EVkSDhsd7DoJBj7hm+Ni7D3qYbb+Rr8DuM8nRanBvkVO9d7askreXGnQ== - dependencies: - concat-with-sourcemaps "*" - lodash.template "^4.4.0" - through2 "^2.0.0" - -handlebars-utils@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/handlebars-utils/-/handlebars-utils-1.0.6.tgz#cb9db43362479054782d86ffe10f47abc76357f9" - integrity sha512-d5mmoQXdeEqSKMtQQZ9WkiUcO1E3tPbWxluCK9hVgIDPzQa9WsKo3Lbe/sGflTe7TomHEeZaOgwIkyIr1kfzkw== - dependencies: - kind-of "^6.0.0" - typeof-article "^0.1.1" - -handlebars@^4.7.6, handlebars@^4.7.7: - version "4.7.7" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" - integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== - dependencies: - minimist "^1.2.5" - neo-async "^2.6.0" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -2111,11 +1315,6 @@ has-symbol-support-x@^1.4.1: resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== -has-symbols@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - has-to-string-tag-x@^1.2.0: version "1.4.1" resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" @@ -2123,64 +1322,11 @@ has-to-string-tag-x@^1.2.0: dependencies: has-symbol-support-x "^1.4.1" -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has-unicode@^2.0.0, has-unicode@^2.0.1: +has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-value@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-2.0.2.tgz#d0f12e8780ba8e90e66ad1a21c707fdb67c25658" - integrity sha512-ybKOlcRsK2MqrM3Hmz/lQxXHZ6ejzSPzpNabKB45jb5qDgJvKPa3SdapTsTLwEb9WltgWpOmNax7i+DzNOk4TA== - dependencies: - get-value "^3.0.0" - has-values "^2.0.1" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has-values@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-2.0.1.tgz#3876200ff86d8a8546a9264a952c17d5fc17579d" - integrity sha512-+QdH3jOmq9P8GfdjFg0eJudqx1FqU62NQJ4P16rOEHeRdl7ckgwn6uqQjzYE0ZoHVV/e5E2esuJ5Gl5+HUW19w== - dependencies: - kind-of "^6.0.2" - has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -2188,57 +1334,11 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -helper-md@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/helper-md/-/helper-md-0.2.2.tgz#c1f59d7e55bbae23362fd8a0e971607aec69d41f" - integrity sha512-49TaQzK+Ic7ZVTq4i1UZxRUJEmAilTk8hz7q4I0WNUaTclLR8ArJV5B3A1fe1xF2HtsDTr2gYKLaVTof/Lt84Q== - dependencies: - ent "^2.2.0" - extend-shallow "^2.0.1" - fs-exists-sync "^0.1.0" - remarkable "^1.6.2" - -html-tag@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/html-tag/-/html-tag-2.0.0.tgz#36c3bc8d816fd30b570d5764a497a641640c2fed" - integrity sha512-XxzooSo6oBoxBEUazgjdXj7VwTn/iSTSZzTYKzYY6I916tkaYzypHxy+pbVU1h+0UQ9JlVf5XkNQyxOAiiQO1g== - dependencies: - is-self-closing "^1.0.1" - kind-of "^6.0.0" - -http-assert@^1.3.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.5.0.tgz#c389ccd87ac16ed2dfa6246fd73b926aa00e6b8f" - integrity sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w== - dependencies: - deep-equal "~1.0.1" - http-errors "~1.8.0" - http-cache-semantics@3.8.1: version "3.8.1" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== -http-errors@^1.6.3, http-errors@~1.8.0: - version "1.8.1" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" - integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.1" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -2254,12 +1354,7 @@ iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -ieee754@1.1.13: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== - -ieee754@^1.1.13, ieee754@^1.1.4: +ieee754@^1.1.13: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -2355,38 +1450,7 @@ into-stream@^6.0.0: from2 "^2.3.0" p-is-promise "^3.0.0" -ioredis@4.28.0: - version "4.28.0" - resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.28.0.tgz#5a2be3f37ff2075e2332f280eaeb02ab4d9ff0d3" - integrity sha512-I+zkeeWp3XFgPT2CtJKxvaF5FjGBGt4yGYljRjQecdQKteThuAsKqffeF1lgHVlYnuNeozRbPOCDNZ7tDWPeig== - dependencies: - cluster-key-slot "^1.1.0" - debug "^4.3.1" - denque "^1.1.0" - lodash.defaults "^4.2.0" - lodash.flatten "^4.4.0" - lodash.isarguments "^3.1.0" - p-map "^2.1.0" - redis-commands "1.7.0" - redis-errors "^1.2.0" - redis-parser "^3.0.0" - standard-as-callback "^2.1.0" - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - -is-buffer@^1.1.5, is-buffer@~1.1.6: +is-buffer@~1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== @@ -2405,57 +1469,6 @@ is-core-module@^2.9.0: dependencies: has "^1.0.3" -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-even@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-even/-/is-even-1.0.0.tgz#76b5055fbad8d294a86b6a949015e1c97b717c06" - integrity sha512-LEhnkAdJqic4Dbqn58A0y52IXoHWlsueqQkKfMfdEnIYG8A1sm/GHidKkS6yvXlMoRrkM34csHnXQtOqcb+Jzg== - dependencies: - is-odd "^0.1.2" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -2473,13 +1486,6 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-generator-function@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" - integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== - dependencies: - has-tostringtag "^1.0.0" - is-glob@^4.0.0, is-glob@^4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -2492,20 +1498,6 @@ is-natural-number@^4.0.1: resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" integrity sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ== -is-number@^2.0.2: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - integrity sha512-QUzH43Gfb9+5yckcrSA0VBDwEtDUchrk4F6tfJZQuNzDJbEDB9cZNzSfXGQ1jqmdDY/kl41lUOWM9syA8z8jlg== - dependencies: - kind-of "^3.0.2" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== - dependencies: - kind-of "^3.0.2" - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -2516,25 +1508,11 @@ is-object@^1.0.1: resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== -is-odd@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-0.1.2.tgz#bc573b5ce371ef2aad6e6f49799b72bef13978a7" - integrity sha512-Ri7C2K7o5IrUU9UEI8losXJCCD/UtsaIrkR5sxIcFg4xQ9cRJXlWA5DQvTE0yDc0krvSNLsRGXN11UPS6KyfBw== - dependencies: - is-number "^3.0.0" - is-plain-obj@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - is-retry-allowed@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" @@ -2545,34 +1523,17 @@ is-retry-allowed@^2.2.0: resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz#88f34cbd236e043e71b6932d09b0c65fb7b4d71d" integrity sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg== -is-self-closing@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-self-closing/-/is-self-closing-1.0.1.tgz#5f406b527c7b12610176320338af0fa3896416e4" - integrity sha512-E+60FomW7Blv5GXTlYee2KDrnG6srxF7Xt1SjrhWUGUEsTFIqY/nq2y3DaftCsgUMdh89V07IVfhY9KIJhLezg== - dependencies: - self-closing-tags "^1.0.1" - is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: +isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== @@ -2582,28 +1543,6 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -isobject@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-0.2.0.tgz#a3432192f39b910b5f02cc989487836ec70aa85e" - integrity sha512-VaWq6XYAsbvM0wf4dyBO7WH9D7GosB7ZZlqrawI9BBiTMINBeCyqSKBa35m870MY3O4aM31pYyZi9DfGrYMJrQ== - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== - isurl@^1.0.0-alpha5: version "1.0.0" resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" @@ -2612,11 +1551,6 @@ isurl@^1.0.0-alpha5: has-to-string-tag-x "^1.2.0" is-object "^1.0.1" -jmespath@0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" - integrity sha512-+kHj8HXArPfpPEKGLZ+kB5ONRTCiGQXo8RQYL0hH8t6pWXUBBK5KkkQmTNOwKK4LEsd0yTsgtjJVm4UBSZea4w== - joi@17.6.0: version "17.6.0" resolved "https://registry.yarnpkg.com/joi/-/joi-17.6.0.tgz#0bb54f2f006c09a96e75ce687957bd04290054b2" @@ -2646,11 +1580,6 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== - json-buffer@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" @@ -2666,17 +1595,12 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-schema@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" - integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: +json-stringify-safe@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== @@ -2690,56 +1614,6 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsonwebtoken@8.5.1, jsonwebtoken@^8.2.0: - version "8.5.1" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" - integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== - dependencies: - jws "^3.2.2" - lodash.includes "^4.3.0" - lodash.isboolean "^3.0.3" - lodash.isinteger "^4.0.4" - lodash.isnumber "^3.0.3" - lodash.isplainobject "^4.0.6" - lodash.isstring "^4.0.1" - lodash.once "^4.0.0" - ms "^2.1.1" - semver "^5.6.0" - -jsprim@^1.2.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" - integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.4.0" - verror "1.10.0" - -jwa@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" - integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== - dependencies: - buffer-equal-constant-time "1.0.1" - ecdsa-sig-formatter "1.0.11" - safe-buffer "^5.0.1" - -jws@^3.0.0, jws@^3.1.4, jws@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" - integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== - dependencies: - jwa "^1.4.1" - safe-buffer "^5.0.1" - -keygrip@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226" - integrity sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ== - dependencies: - tsscmp "1.0.6" - keyv@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" @@ -2747,79 +1621,6 @@ keyv@3.0.0: dependencies: json-buffer "3.0.0" -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.1.0, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0, kind-of@^5.0.2: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -koa-compose@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877" - integrity sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw== - -koa-convert@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-2.0.0.tgz#86a0c44d81d40551bae22fee6709904573eea4f5" - integrity sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA== - dependencies: - co "^4.6.0" - koa-compose "^4.1.0" - -koa-passport@4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/koa-passport/-/koa-passport-4.1.4.tgz#5f1665c1c2a37ace79af9f970b770885ca30ccfa" - integrity sha512-dJBCkl4X+zdYxbI2V2OtoGy0PUenpvp2ZLLWObc8UJhsId0iQpTFT8RVcuA0709AL2txGwRHnSPoT1bYNGa6Kg== - dependencies: - passport "^0.4.0" - -koa@^2.13.4: - version "2.13.4" - resolved "https://registry.yarnpkg.com/koa/-/koa-2.13.4.tgz#ee5b0cb39e0b8069c38d115139c774833d32462e" - integrity sha512-43zkIKubNbnrULWlHdN5h1g3SEKXOEzoAlRsHOTFpnlDu8JlAOZSMJBLULusuXRequboiwJcj5vtYXKB3k7+2g== - dependencies: - accepts "^1.3.5" - cache-content-type "^1.0.0" - content-disposition "~0.5.2" - content-type "^1.0.4" - cookies "~0.8.0" - debug "^4.3.2" - delegates "^1.0.0" - depd "^2.0.0" - destroy "^1.0.4" - encodeurl "^1.0.2" - escape-html "^1.0.3" - fresh "~0.5.2" - http-assert "^1.3.0" - http-errors "^1.6.3" - is-generator-function "^1.0.7" - koa-compose "^4.1.0" - koa-convert "^2.0.0" - on-finished "^2.3.0" - only "~0.0.2" - parseurl "^1.3.2" - statuses "^1.5.0" - type-is "^1.6.16" - vary "^1.1.2" - level-codec@9.0.2, level-codec@^9.0.0: version "9.0.2" resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.2.tgz#fd60df8c64786a80d44e63423096ffead63d8cbc" @@ -2939,102 +1740,27 @@ load-module@^4.2.1: dependencies: array-back "^6.2.0" -lodash._reinterpolate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" - integrity sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA== - lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== -lodash.defaults@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" - integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== - -lodash.flatten@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" - integrity sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g== - -lodash.includes@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" - integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== - -lodash.isarguments@3.1.0, lodash.isarguments@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" - integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== - -lodash.isboolean@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" - integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== - -lodash.isinteger@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" - integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== - -lodash.isnumber@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" - integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== - -lodash.isplainobject@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" - integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== - -lodash.isstring@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" - integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== - lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.noop@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash.noop/-/lodash.noop-3.0.1.tgz#38188f4d650a3a474258439b96ec45b32617133c" - integrity sha512-TmYdmu/pebrdTIBDK/FDx9Bmfzs9x0sZG6QIJuMDTqEPfeciLcN13ij+cOd0i9vwJfBtbG9UQ+C7MkXgYxrIJg== - -lodash.once@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" - integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== - lodash.pick@^4.0.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q== -lodash.template@^4.4.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" - integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== - dependencies: - lodash._reinterpolate "^3.0.0" - lodash.templatesettings "^4.0.0" - -lodash.templatesettings@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" - integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== - dependencies: - lodash._reinterpolate "^3.0.0" - lodash.truncate@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== -lodash@4.17.21, lodash@^4.14.0, lodash@^4.17.20, lodash@^4.17.21: +lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -3081,25 +1807,6 @@ make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" -make-dir@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== - dependencies: - object-visit "^1.0.0" - md5@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f" @@ -3109,45 +1816,11 @@ md5@^2.3.0: crypt "0.0.2" is-buffer "~1.1.6" -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== - -merge-descriptors@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== - merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -methods@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== - -micromatch@^3.1.5: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - micromatch@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" @@ -3156,23 +1829,11 @@ micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" -mime-db@1.52.0, mime-db@^1.28.0: +mime-db@^1.28.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mime@^1.3.4, mime@^1.4.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -3195,7 +1856,7 @@ minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.1.1: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== @@ -3215,14 +1876,6 @@ minizlib@^2.1.1: minipass "^3.0.0" yallist "^4.0.0" -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" @@ -3233,17 +1886,12 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.1.1, ms@^2.1.3: +ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -3261,23 +1909,6 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - napi-build-utils@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" @@ -3303,16 +1934,6 @@ ndjson@^1.4.3: split2 "^2.1.0" through2 "^2.0.3" -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -neo-async@^2.6.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - node-abi@^2.21.0: version "2.30.1" resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.30.1.tgz#c437d4b1fe0e285aaf290d45b45d4d7afedac4cf" @@ -3320,49 +1941,18 @@ node-abi@^2.21.0: dependencies: semver "^5.4.1" -node-addon-api@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" - integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== - -node-fetch@2, node-fetch@2.6.7, node-fetch@^2.6.6, node-fetch@^2.6.7: +node-fetch@2, node-fetch@2.6.7, node-fetch@^2.6.6: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== dependencies: whatwg-url "^5.0.0" -node-fetch@2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" - integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== - -node-forge@^0.7.1: - version "0.7.6" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.6.tgz#fdf3b418aee1f94f0ef642cd63486c77ca9724ac" - integrity sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw== - node-gyp-build@~4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.1.1.tgz#d7270b5d86717068d114cc57fff352f96d745feb" integrity sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ== -node-mocks-http@^1.11.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/node-mocks-http/-/node-mocks-http-1.11.0.tgz#defc0febf6b935f08245397d47534a8de592996e" - integrity sha512-jS/WzSOcKbOeGrcgKbenZeNhxUNnP36Yw11+hL4TTxQXErGfqYZ+MaYNNvhaTiGIJlzNSqgQkk9j8dSu1YWSuw== - dependencies: - accepts "^1.3.7" - content-disposition "^0.5.3" - depd "^1.1.0" - fresh "^0.5.2" - merge-descriptors "^1.0.1" - methods "^1.1.2" - mime "^1.3.4" - parseurl "^1.3.3" - range-parser "^1.2.0" - type-is "^1.6.18" - noms@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/noms/-/noms-0.0.0.tgz#da8ebd9f3af9d6760919b27d9cdc8092a7332859" @@ -3371,13 +1961,6 @@ noms@0.0.0: inherits "^2.0.1" readable-stream "~1.0.31" -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" - normalize-url@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" @@ -3397,66 +1980,16 @@ npmlog@^4.0.1: gauge "~2.7.3" set-blocking "~2.0.0" -npmlog@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" - integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== - dependencies: - are-we-there-yet "^2.0.0" - console-control-strings "^1.1.0" - gauge "^3.0.0" - set-blocking "^2.0.0" - number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -oauth@0.9.x, oauth@^0.9.15: - version "0.9.15" - resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" - integrity sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA== - -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== - dependencies: - isobject "^3.0.0" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== - dependencies: - isobject "^3.0.1" - -on-finished@^2.3.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -3471,11 +2004,6 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" -only@~0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" - integrity sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ== - optionator@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" @@ -3532,11 +2060,6 @@ p-is-promise@^3.0.0: resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-3.0.0.tgz#58e78c7dfe2e163cf2a04ff869e7c1dba64a5971" integrity sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ== -p-map@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" - integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== - p-timeout@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" @@ -3551,99 +2074,6 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parseurl@^1.3.2, parseurl@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== - -passport-google-auth@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/passport-google-auth/-/passport-google-auth-1.0.2.tgz#8b300b5aa442ef433de1d832ed3112877d0b2938" - integrity sha512-cfAqna6jZLyMEwUdd4PIwAh2mQKQVEDAaRIaom1pG6h4x4Gwjllf/Jflt3TkR1Sen5Rkvr3l7kSXCWE1EKkh8g== - dependencies: - googleapis "^16.0.0" - passport-strategy "1.x" - -passport-google-oauth1@1.x.x: - version "1.0.0" - resolved "https://registry.yarnpkg.com/passport-google-oauth1/-/passport-google-oauth1-1.0.0.tgz#af74a803df51ec646f66a44d82282be6f108e0cc" - integrity sha512-qpCEhuflJgYrdg5zZIpAq/K3gTqa1CtHjbubsEsidIdpBPLkEVq6tB1I8kBNcH89RdSiYbnKpCBXAZXX/dtx1Q== - dependencies: - passport-oauth1 "1.x.x" - -passport-google-oauth20@2.x.x: - version "2.0.0" - resolved "https://registry.yarnpkg.com/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz#0d241b2d21ebd3dc7f2b60669ec4d587e3a674ef" - integrity sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ== - dependencies: - passport-oauth2 "1.x.x" - -passport-google-oauth@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/passport-google-oauth/-/passport-google-oauth-2.0.0.tgz#f6eb4bc96dd6c16ec0ecfdf4e05ec48ca54d4dae" - integrity sha512-JKxZpBx6wBQXX1/a1s7VmdBgwOugohH+IxCy84aPTZNq/iIPX6u7Mqov1zY7MKRz3niFPol0KJz8zPLBoHKtYA== - dependencies: - passport-google-oauth1 "1.x.x" - passport-google-oauth20 "2.x.x" - -passport-jwt@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065" - integrity sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg== - dependencies: - jsonwebtoken "^8.2.0" - passport-strategy "^1.0.0" - -passport-local@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/passport-local/-/passport-local-1.0.0.tgz#1fe63268c92e75606626437e3b906662c15ba6ee" - integrity sha512-9wCE6qKznvf9mQYYbgJ3sVOHmCWoUNMVFoZzNoznmISbhnNNPhN9xfY3sLmScHMetEJeoY7CXwfhCe7argfQow== - dependencies: - passport-strategy "1.x.x" - -passport-oauth1@1.x.x: - version "1.2.0" - resolved "https://registry.yarnpkg.com/passport-oauth1/-/passport-oauth1-1.2.0.tgz#5229d431781bf5b265bec86ce9a9cce58a756cf9" - integrity sha512-Sv2YWodC6jN12M/OXwmR4BIXeeIHjjbwYTQw4kS6tHK4zYzSEpxBgSJJnknBjICA5cj0ju3FSnG1XmHgIhYnLg== - dependencies: - oauth "0.9.x" - passport-strategy "1.x.x" - utils-merge "1.x.x" - -passport-oauth2-refresh@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/passport-oauth2-refresh/-/passport-oauth2-refresh-2.1.0.tgz#c31cd133826383f5539d16ad8ab4f35ca73ce4a4" - integrity sha512-4ML7ooCESCqiTgdDBzNUFTBcPR8zQq9iM6eppEUGMMvLdsjqRL93jKwWm4Az3OJcI+Q2eIVyI8sVRcPFvxcF/A== - -passport-oauth2@1.x.x: - version "1.6.1" - resolved "https://registry.yarnpkg.com/passport-oauth2/-/passport-oauth2-1.6.1.tgz#c5aee8f849ce8bd436c7f81d904a3cd1666f181b" - integrity sha512-ZbV43Hq9d/SBSYQ22GOiglFsjsD1YY/qdiptA+8ej+9C1dL1TVB+mBE5kDH/D4AJo50+2i8f4bx0vg4/yDDZCQ== - dependencies: - base64url "3.x.x" - oauth "0.9.x" - passport-strategy "1.x.x" - uid2 "0.0.x" - utils-merge "1.x.x" - -passport-strategy@1.x, passport-strategy@1.x.x, passport-strategy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" - integrity sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA== - -passport@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.1.tgz#941446a21cb92fc688d97a0861c38ce9f738f270" - integrity sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg== - dependencies: - passport-strategy "1.x.x" - pause "0.0.1" - path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -3664,21 +2094,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -pause@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" - integrity sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg== - pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== - picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -3745,11 +2165,6 @@ pkg@5.7.0: resolve "^1.22.0" stream-meter "^1.0.4" -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== - posthog-node@1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/posthog-node/-/posthog-node-1.0.7.tgz#a7a9525eebff23312117e57cff3ddac82afb2262" @@ -3764,20 +2179,6 @@ posthog-node@1.0.7: remove-trailing-slash "^0.1.1" uuid "^8.3.2" -posthog-node@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/posthog-node/-/posthog-node-1.3.0.tgz#804ed2f213a2f05253f798bf9569d55a9cad94f7" - integrity sha512-2+VhqiY/rKIqKIXyvemBFHbeijHE25sP7eKltnqcFqAssUE6+sX6vusN9A4luzToOqHQkUZexiCKxvuGagh7JA== - dependencies: - axios "0.24.0" - axios-retry "^3.1.9" - component-type "^1.2.1" - join-component "^1.1.0" - md5 "^2.3.0" - ms "^2.1.3" - remove-trailing-slash "^0.1.1" - uuid "^8.3.2" - pouch-stream@^0.4.0: version "0.4.1" resolved "https://registry.yarnpkg.com/pouch-stream/-/pouch-stream-0.4.1.tgz#0c6d8475c9307677627991a2f079b301c3b89bdd" @@ -3786,84 +2187,6 @@ pouch-stream@^0.4.0: inherits "^2.0.1" readable-stream "^1.0.27-1" -pouchdb-abstract-mapreduce@7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/pouchdb-abstract-mapreduce/-/pouchdb-abstract-mapreduce-7.2.2.tgz#dd1b10a83f8d24361dce9aaaab054614b39f766f" - integrity sha512-7HWN/2yV2JkwMnGnlp84lGvFtnm0Q55NiBUdbBcaT810+clCGKvhssBCrXnmwShD1SXTwT83aszsgiSfW+SnBA== - dependencies: - pouchdb-binary-utils "7.2.2" - pouchdb-collate "7.2.2" - pouchdb-collections "7.2.2" - pouchdb-errors "7.2.2" - pouchdb-fetch "7.2.2" - pouchdb-mapreduce-utils "7.2.2" - pouchdb-md5 "7.2.2" - pouchdb-utils "7.2.2" - -pouchdb-binary-utils@7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/pouchdb-binary-utils/-/pouchdb-binary-utils-7.2.2.tgz#0690b348052c543b1e67f032f47092ca82bcb10e" - integrity sha512-shacxlmyHbUrNfE6FGYpfyAJx7Q0m91lDdEAaPoKZM3SzAmbtB1i+OaDNtYFztXjJl16yeudkDb3xOeokVL3Qw== - dependencies: - buffer-from "1.1.1" - -pouchdb-collate@7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/pouchdb-collate/-/pouchdb-collate-7.2.2.tgz#fc261f5ef837c437e3445fb0abc3f125d982c37c" - integrity sha512-/SMY9GGasslknivWlCVwXMRMnQ8myKHs4WryQ5535nq1Wj/ehpqWloMwxEQGvZE1Sda3LOm7/5HwLTcB8Our+w== - -pouchdb-collections@7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/pouchdb-collections/-/pouchdb-collections-7.2.2.tgz#aeed77f33322429e3f59d59ea233b48ff0e68572" - integrity sha512-6O9zyAYlp3UdtfneiMYuOCWdUCQNo2bgdjvNsMSacQX+3g8WvIoFQCYJjZZCpTttQGb+MHeRMr8m2U95lhJTew== - -pouchdb-errors@7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/pouchdb-errors/-/pouchdb-errors-7.2.2.tgz#80d811d65c766c9d20b755c6e6cc123f8c3c4792" - integrity sha512-6GQsiWc+7uPfgEHeavG+7wuzH3JZW29Dnrvz8eVbDFE50kVFxNDVm3EkYHskvo5isG7/IkOx7PV7RPTA3keG3g== - dependencies: - inherits "2.0.4" - -pouchdb-fetch@7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/pouchdb-fetch/-/pouchdb-fetch-7.2.2.tgz#492791236d60c899d7e9973f9aca0d7b9cc02230" - integrity sha512-lUHmaG6U3zjdMkh8Vob9GvEiRGwJfXKE02aZfjiVQgew+9SLkuOxNw3y2q4d1B6mBd273y1k2Lm0IAziRNxQnA== - dependencies: - abort-controller "3.0.0" - fetch-cookie "0.10.1" - node-fetch "2.6.0" - -pouchdb-find@7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/pouchdb-find/-/pouchdb-find-7.2.2.tgz#1227afdd761812d508fe0794b3e904518a721089" - integrity sha512-BmFeFVQ0kHmDehvJxNZl9OmIztCjPlZlVSdpijuFbk/Fi1EFPU1BAv3kLC+6DhZuOqU/BCoaUBY9sn66pPY2ag== - dependencies: - pouchdb-abstract-mapreduce "7.2.2" - pouchdb-collate "7.2.2" - pouchdb-errors "7.2.2" - pouchdb-fetch "7.2.2" - pouchdb-md5 "7.2.2" - pouchdb-selector-core "7.2.2" - pouchdb-utils "7.2.2" - -pouchdb-mapreduce-utils@7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/pouchdb-mapreduce-utils/-/pouchdb-mapreduce-utils-7.2.2.tgz#13a46a3cc2a3f3b8e24861da26966904f2963146" - integrity sha512-rAllb73hIkU8rU2LJNbzlcj91KuulpwQu804/F6xF3fhZKC/4JQMClahk+N/+VATkpmLxp1zWmvmgdlwVU4HtQ== - dependencies: - argsarray "0.0.1" - inherits "2.0.4" - pouchdb-collections "7.2.2" - pouchdb-utils "7.2.2" - -pouchdb-md5@7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/pouchdb-md5/-/pouchdb-md5-7.2.2.tgz#415401acc5a844112d765bd1fb4e5d9f38fb0838" - integrity sha512-c/RvLp2oSh8PLAWU5vFBnp6ejJABIdKqboZwRRUrWcfGDf+oyX8RgmJFlYlzMMOh4XQLUT1IoaDV8cwlsuryZw== - dependencies: - pouchdb-binary-utils "7.2.2" - spark-md5 "3.0.1" - pouchdb-promise@^6.0.4: version "6.4.3" resolved "https://registry.yarnpkg.com/pouchdb-promise/-/pouchdb-promise-6.4.3.tgz#74516f4acf74957b54debd0fb2c0e5b5a68ca7b3" @@ -3884,28 +2207,6 @@ pouchdb-replication-stream@1.2.9: pouchdb-promise "^6.0.4" through2 "^2.0.0" -pouchdb-selector-core@7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/pouchdb-selector-core/-/pouchdb-selector-core-7.2.2.tgz#264d7436a8c8ac3801f39960e79875ef7f3879a0" - integrity sha512-XYKCNv9oiNmSXV5+CgR9pkEkTFqxQGWplnVhO3W9P154H08lU0ZoNH02+uf+NjZ2kjse7Q1fxV4r401LEcGMMg== - dependencies: - pouchdb-collate "7.2.2" - pouchdb-utils "7.2.2" - -pouchdb-utils@7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/pouchdb-utils/-/pouchdb-utils-7.2.2.tgz#c17c4788f1d052b0daf4ef8797bbc4aaa3945aa4" - integrity sha512-XmeM5ioB4KCfyB2MGZXu1Bb2xkElNwF1qG+zVFbQsKQij0zvepdOUfGuWvLRHxTOmt4muIuSOmWZObZa3NOgzQ== - dependencies: - argsarray "0.0.1" - clone-buffer "1.0.0" - immediate "3.3.0" - inherits "2.0.4" - pouchdb-collections "7.2.2" - pouchdb-errors "7.2.2" - pouchdb-md5 "7.2.2" - uuid "8.1.0" - pouchdb@7.3.0: version "7.3.0" resolved "https://registry.yarnpkg.com/pouchdb/-/pouchdb-7.3.0.tgz#440fbef12dfd8f9002320802528665e883a3b7f8" @@ -3986,7 +2287,7 @@ prr@~1.0.1: resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== -psl@^1.1.28, psl@^1.1.33: +psl@^1.1.33: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== @@ -3999,21 +2300,11 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== - punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -qs@~6.5.2: - version "6.5.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" - integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== - query-string@^5.0.1: version "5.1.1" resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" @@ -4023,11 +2314,6 @@ query-string@^5.0.1: object-assign "^4.1.0" strict-uri-encode "^1.0.0" -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== - querystringify@^2.1.1: version "2.2.0" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" @@ -4045,11 +2331,6 @@ randomstring@1.1.5: dependencies: array-uniq "1.0.2" -range-parser@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" @@ -4107,30 +2388,6 @@ readable-stream@~1.0.31: isarray "0.0.1" string_decoder "~0.10.x" -redis-commands@1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.7.0.tgz#15a6fea2d58281e27b1cd1acfb4b293e278c3a89" - integrity sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ== - -redis-errors@^1.0.0, redis-errors@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" - integrity sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w== - -redis-parser@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" - integrity sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A== - dependencies: - redis-errors "^1.0.0" - -redlock@4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/redlock/-/redlock-4.2.0.tgz#c26590768559afd5fff76aa1133c94b411ff4f5f" - integrity sha512-j+oQlG+dOwcetUt2WJWttu4CZVeRzUrcVcISFmEmfyuwCVSJ93rDT7YSgg7H7rnxwoRyk/jU46kycVka5tW7jA== - dependencies: - bluebird "^3.7.2" - reduce-flatten@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" @@ -4141,34 +2398,11 @@ regenerator-runtime@^0.13.4: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - regexpp@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== -relative@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/relative/-/relative-3.0.2.tgz#0dcd8ec54a5d35a3c15e104503d65375b5a5367f" - integrity sha512-Q5W2qeYtY9GbiR8z1yHNZ1DGhyjb4AnLEjt8iE6XfcC1QIu+FAtj3HQaO0wH28H1mX6cqNLvAqWhP402dxJGyA== - dependencies: - isobject "^2.0.0" - -remarkable@^1.6.2: - version "1.7.4" - resolved "https://registry.yarnpkg.com/remarkable/-/remarkable-1.7.4.tgz#19073cb960398c87a7d6546eaa5e50d2022fcd00" - integrity sha512-e6NKUXgX95whv7IgddywbeN/ItCkWbISmc2DiqHJb0wTrqZIexqdco5b8Z3XZoo/48IdNVKM9ZCvTPJ4F5uvhg== - dependencies: - argparse "^1.0.10" - autolinker "~0.28.0" - remove-trailing-slash@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/remove-trailing-slash/-/remove-trailing-slash-0.1.1.tgz#be2285a59f39c74d1bce4f825950061915e3780d" @@ -4192,42 +2426,6 @@ renamer@^4.0.0: stream-read-all "^3.0.1" typical "^7.1.1" -repeat-element@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" - integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== - -request@^2.72.0, request@^2.74.0, request@^2.88.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -4248,11 +2446,6 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== - resolve@^1.22.0: version "1.22.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" @@ -4277,11 +2470,6 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -4313,7 +2501,7 @@ rxjs@^6.6.6: dependencies: tslib "^1.9.0" -safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -4323,33 +2511,11 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sanitize-s3-objectkey@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/sanitize-s3-objectkey/-/sanitize-s3-objectkey-0.0.1.tgz#efa9887cd45275b40234fb4bb12fc5754fe64e7e" - integrity sha512-ZTk7aqLxy4sD40GWcYWoLfbe05XLmkKvh6vGKe13ADlei24xlezcvjgKy1qRArlaIbIMYaqK7PCalvZtulZlaQ== - -sax@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" - integrity sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA== - -sax@>=0.1.1, sax@>=0.6.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - seek-bzip@^1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.6.tgz#35c4171f55a680916b52a07859ecf3b5857f21c4" @@ -4357,48 +2523,23 @@ seek-bzip@^1.0.5: dependencies: commander "^2.8.1" -self-closing-tags@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/self-closing-tags/-/self-closing-tags-1.0.1.tgz#6c5fa497994bb826b484216916371accee490a5d" - integrity sha512-7t6hNbYMxM+VHXTgJmxwgZgLGktuXtVVD5AivWzNTdJBM4DBjnDKDzkf2SrNjihaArpeJYNjxkELBu1evI4lQA== +semver@^5.4.1, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@7.3.7, semver@^7.2.1, semver@^7.3.5: +semver@^7.2.1, semver@^7.3.5: version "7.3.7" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== dependencies: lru-cache "^6.0.0" -semver@^5.4.1, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -set-blocking@^2.0.0, set-blocking@~2.0.0: +set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -4411,11 +2552,6 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shimmer@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" - integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== - signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" @@ -4449,36 +2585,6 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - sort-keys-length@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" @@ -4500,49 +2606,16 @@ sort-keys@^2.0.0: dependencies: is-plain-obj "^1.0.0" -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-url@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" - integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== - -source-map@^0.5.6: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== - -source-map@^0.6.1, source-map@~0.6.1: +source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -spark-md5@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spark-md5/-/spark-md5-3.0.1.tgz#83a0e255734f2ab4e5c466e5a2cfc9ba2aa2124d" - integrity sha512-0tF3AGSD1ppQeuffsLDIOWlKUd3lS92tFxcsrh5Pe3ZphhnoK+oXIBTzOAThZCiuINZLvpiLH/1VS1/ANEJVig== - spark-md5@3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/spark-md5/-/spark-md5-3.0.2.tgz#7952c4a30784347abcee73268e473b9c0167e3fc" integrity sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw== -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - split2@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493" @@ -4555,44 +2628,6 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== -sshpk@^1.7.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" - integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -standard-as-callback@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45" - integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -"statuses@>= 1.5.0 < 2", statuses@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== - -step@0.0.x: - version "0.0.6" - resolved "https://registry.yarnpkg.com/step/-/step-0.0.6.tgz#143e7849a5d7d3f4a088fe29af94915216eeede2" - integrity sha512-qSSeQinUJk2w38vUFobjFoE307GqsozMC8VisOCkJLpklvKPT0ptPHwWOrENoag8rgLudvTkfP3bancwP93/Jw== - stream-meter@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/stream-meter/-/stream-meter-1.0.4.tgz#52af95aa5ea760a2491716704dbff90f73afdd1d" @@ -4610,11 +2645,6 @@ strict-uri-encode@^1.0.0: resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ== -string-template@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/string-template/-/string-template-1.0.0.tgz#9e9f2233dc00f218718ec379a28a5673ecca8b96" - integrity sha512-SLqR3GBUXuoPP5MmYtD7ompvXiG87QjT6lzOszyXjTM86Uu7At7vNnt2xgyTLq5o9T4IxTYFyGxcULqpsmsfdg== - string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -4690,11 +2720,6 @@ strip-outer@^1.0.0: dependencies: escape-string-regexp "^1.0.2" -striptags@^3.1.1: - version "3.2.0" - resolved "https://registry.yarnpkg.com/striptags/-/striptags-3.2.0.tgz#cc74a137db2de8b0b9a370006334161f7dd67052" - integrity sha512-g45ZOGzHDMe2bdYMdIvdAfCQkCTDMGBazSw1ypMowwGIee7ZQ5dU0rBJ8Jqgl+jAKIv4dbeE1jscZq9wid1Tkw== - supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -4735,7 +2760,7 @@ table@^6.0.9: string-width "^4.2.3" strip-ansi "^6.0.1" -tar-fs@2.1.1, tar-fs@^2.0.0, tar-fs@^2.1.1: +tar-fs@^2.0.0, tar-fs@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== @@ -4769,7 +2794,7 @@ tar-stream@^2.1.4: inherits "^2.0.3" readable-stream "^3.1.1" -tar@6.1.11, tar@^6.1.11: +tar@6.1.11: version "6.1.11" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== @@ -4829,26 +2854,6 @@ to-fast-properties@^2.0.0: resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== -to-gfm-code-block@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/to-gfm-code-block/-/to-gfm-code-block-0.1.1.tgz#25d045a5fae553189e9637b590900da732d8aa82" - integrity sha512-LQRZWyn8d5amUKnfR9A9Uu7x9ss7Re8peuWR2gkh1E+ildOfv2aF26JpuDg8JtvCduu5+hOrMIH+XstZtnagqg== - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -4856,21 +2861,6 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - "tough-cookie@^2.3.3 || ^3.0.1 || ^4.0.0": version "4.1.2" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" @@ -4881,14 +2871,6 @@ toidentifier@1.0.1: universalify "^0.2.0" url-parse "^1.5.3" -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -4906,11 +2888,6 @@ tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tsscmp@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" - integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== - tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -4918,11 +2895,6 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== - type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -4947,21 +2919,6 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -type-is@^1.6.16, type-is@^1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -typeof-article@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/typeof-article/-/typeof-article-0.1.1.tgz#9f07e733c3fbb646ffa9e61c08debacd460e06af" - integrity sha512-Vn42zdX3FhmUrzEmitX3iYyLb+Umwpmv8fkZRIknYh84lmdrwqZA5xYaoKiIj2Rc5i/5wcDrpUmZcbk1U51vTw== - dependencies: - kind-of "^3.1.0" - typical@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" @@ -4977,16 +2934,6 @@ typical@^7.1.1: resolved "https://registry.yarnpkg.com/typical/-/typical-7.1.1.tgz#ba177ab7ab103b78534463ffa4c0c9754523ac1f" integrity sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA== -uglify-js@^3.1.4: - version "3.17.1" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.1.tgz#1258a2a488147a8266b3034499ce6959978ba7f4" - integrity sha512-+juFBsLLw7AqMaqJ0GFvlsGZwdQfI2ooKQB39PSBgMnMakcFosi9O8jCwE+2/2nMNcc0z63r9mwjoDG8zr+q0Q== - -uid2@0.0.x: - version "0.0.4" - resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.4.tgz#033f3b1d5d32505f5ce5f888b9f3b667123c0a44" - integrity sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA== - unbzip2-stream@^1.0.9: version "1.4.3" resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" @@ -4995,16 +2942,6 @@ unbzip2-stream@^1.0.9: buffer "^5.2.1" through "^2.3.8" -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - universalify@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" @@ -5015,14 +2952,6 @@ universalify@^2.0.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - untildify@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" @@ -5035,11 +2964,6 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== - url-parse-lax@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" @@ -5060,89 +2984,26 @@ url-to-options@^1.0.1: resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" integrity sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A== -url@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" - integrity sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ== - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -utils-merge@1.x.x: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== - -uuid@3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== - -uuid@8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.1.0.tgz#6f1536eb43249f473abc6bd58ff983da1ca30d8d" - integrity sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg== - uuid@8.3.2, uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - v8-compile-cache@^2.0.3: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== -vary@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -vm2@^3.9.4: - version "3.9.11" - resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.11.tgz#a880f510a606481719ec3f9803b940c5805a06fe" - integrity sha512-PFG8iJRSjvvBdisowQ7iVF580DXb1uCIiGaXgm7tynMR1uTBlv7UJlB1zdv5KJ+Tmq1f0Upnj3fayoEOPpCBKg== - dependencies: - acorn "^8.7.0" - acorn-walk "^8.2.0" - vuvuzela@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/vuvuzela/-/vuvuzela-1.0.3.tgz#3be145e58271c73ca55279dd851f12a682114b0b" integrity sha512-Tm7jR1xTzBbPW+6y1tknKiEhz04Wf/1iZkcTJjSFcpNko43+dFW6+OOeQe9taJIug3NdfUAjFKgUSyQrIKaDvQ== -webfinger@^0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/webfinger/-/webfinger-0.4.2.tgz#3477a6d97799461896039fcffc650b73468ee76d" - integrity sha512-PvvQ/k74HkC3q5G7bGu4VYeKDt3ePZMzT5qFPtEnOL8eyIU1/06OtDn9X5vlkQ23BlegA3eN89rDLiYUife3xQ== - dependencies: - step "0.0.x" - xml2js "0.1.x" - webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -5163,7 +3024,7 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -wide-align@^1.1.0, wide-align@^1.1.2: +wide-align@^1.1.0: version "1.1.5" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== @@ -5175,11 +3036,6 @@ word-wrap@^1.2.3, word-wrap@~1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== -wordwrap@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== - wordwrapjs@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f" @@ -5209,26 +3065,6 @@ write-stream@~0.4.3: dependencies: readable-stream "~0.0.2" -xml2js@0.1.x: - version "0.1.14" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.1.14.tgz#5274e67f5a64c5f92974cd85139e0332adc6b90c" - integrity sha512-pbdws4PPPNc1HPluSUKamY4GWMk592K7qwcj6BExbVOhhubub8+pMda/ql68b6L3luZs/OGjGSB5goV7SnmgnA== - dependencies: - sax ">=0.1.1" - -xml2js@0.4.19: - version "0.4.19" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" - integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== - dependencies: - sax ">=0.6.0" - xmlbuilder "~9.0.1" - -xmlbuilder@~9.0.1: - version "9.0.7" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" - integrity sha512-7YXTQc3P2l9+0rjaUbLwMKRhtmwg1M1eDf6nag7urC7pIPYLD9W/jmzQ4ptRSUbodw5S0jfoGTflLemQibSpeQ== - xtend@^4.0.0, xtend@^4.0.2, xtend@~4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" @@ -5269,18 +3105,3 @@ yauzl@^2.4.2: dependencies: buffer-crc32 "~0.2.3" fd-slicer "~1.1.0" - -year@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/year/-/year-0.2.1.tgz#4083ae520a318b23ec86037f3000cb892bdf9bb0" - integrity sha512-9GnJUZ0QM4OgXuOzsKNzTJ5EOkums1Xc+3YQXp+Q+UxFjf7zLucp9dQ8QMIft0Szs1E1hUiXFim1OYfEKFq97w== - -ylru@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.3.2.tgz#0de48017473275a4cbdfc83a1eaf67c01af8a785" - integrity sha512-RXRJzMiK6U2ye0BlGGZnmpwJDPgakn6aNQ0A7gHRbD4I0uvK4TW6UqkK1V0pp9jskjJBAXd3dRrbzWkqJ+6cxA== - -zlib@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/zlib/-/zlib-1.0.5.tgz#6e7c972fc371c645a6afb03ab14769def114fcc0" - integrity sha512-40fpE2II+Cd3k8HWTWONfeKE2jL+P42iWJ1zzps5W51qcTsOUKM5Q5m2PFb0CLxlmFAaUuUdJGc3OfZy947v0w== diff --git a/packages/client/package.json b/packages/client/package.json index 3e0f7937e2..bc142d8c94 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "1.4.17", + "version": "1.4.18-alpha.0", "license": "MPL-2.0", "module": "dist/budibase-client.js", "main": "dist/budibase-client.js", @@ -19,9 +19,9 @@ "dev:builder": "rollup -cw" }, "dependencies": { - "@budibase/bbui": "^1.4.17", - "@budibase/frontend-core": "^1.4.17", - "@budibase/string-templates": "^1.4.17", + "@budibase/bbui": "1.4.18-alpha.0", + "@budibase/frontend-core": "1.4.18-alpha.0", + "@budibase/string-templates": "1.4.18-alpha.0", "@spectrum-css/button": "^3.0.3", "@spectrum-css/card": "^3.0.3", "@spectrum-css/divider": "^1.0.3", @@ -35,7 +35,6 @@ "downloadjs": "1.4.7", "leaflet": "^1.7.1", "regexparam": "^1.3.0", - "rollup-plugin-polyfill-node": "^0.8.0", "sanitize-html": "^2.7.0", "screenfull": "^6.0.1", "shortid": "^2.2.15", @@ -52,6 +51,7 @@ "postcss": "^8.2.10", "rollup": "^2.44.0", "rollup-plugin-json": "^4.0.0", + "rollup-plugin-polyfill-node": "^0.8.0", "rollup-plugin-postcss": "^4.0.0", "rollup-plugin-svelte": "^7.1.0", "rollup-plugin-svg": "^2.0.0", diff --git a/packages/client/src/components/Component.svelte b/packages/client/src/components/Component.svelte index b72fa16216..2d586df24d 100644 --- a/packages/client/src/components/Component.svelte +++ b/packages/client/src/components/Component.svelte @@ -142,6 +142,10 @@ // Determine and apply settings to the component $: applySettings(staticSettings, enrichedSettings, conditionalSettings) + // Determine custom css. + // Broken out as a separate variable to minimize reactivity updates. + $: customCSS = cachedSettings?._css + // Scroll the selected element into view $: selected && scrollIntoView() @@ -151,6 +155,7 @@ children: children.length, styles: { ...instance._styles, + custom: customCSS, id, empty: emptyState, interactive, @@ -249,14 +254,18 @@ // Get raw settings let settings = {} Object.entries(instance) - .filter(([name]) => name === "_conditions" || !name.startsWith("_")) + .filter(([name]) => !name.startsWith("_")) .forEach(([key, value]) => { settings[key] = value }) - - // Derive static, dynamic and nested settings if the instance changed let newStaticSettings = { ...settings } let newDynamicSettings = { ...settings } + + // Attach some internal properties + newDynamicSettings["_conditions"] = instance._conditions + newDynamicSettings["_css"] = instance._styles?.custom + + // Derive static, dynamic and nested settings if the instance changed settingsDefinition?.forEach(setting => { if (setting.nested) { delete newDynamicSettings[setting.key] @@ -370,6 +379,11 @@ // setting it on initialSettings directly, we avoid a double render. cachedSettings[key] = allSettings[key] + // Don't update components for internal properties + if (key.startsWith("_")) { + return + } + if (ref?.$$set) { // Programmatically set the prop to avoid svelte reactive statements // firing inside components. This circumvents the problems caused by diff --git a/packages/client/src/licensing/features.js b/packages/client/src/licensing/features.js index 98e03b77d2..1f0d4a4870 100644 --- a/packages/client/src/licensing/features.js +++ b/packages/client/src/licensing/features.js @@ -1,6 +1,5 @@ -// import { isFreePlan } from "./utils.js" +import { isFreePlan } from "./utils.js" export const logoEnabled = () => { - return false - // return isFreePlan() + return isFreePlan() } diff --git a/packages/client/src/sdk.js b/packages/client/src/sdk.js index aa778388f6..1afeea0055 100644 --- a/packages/client/src/sdk.js +++ b/packages/client/src/sdk.js @@ -17,6 +17,7 @@ import { getAction } from "utils/getAction" import Provider from "components/context/Provider.svelte" import { ActionTypes } from "./constants" import { fetchDatasourceSchema } from "./utils/schema.js" +import { getAPIKey } from "./utils/api.js" export default { API, @@ -36,4 +37,5 @@ export default { fetchDatasourceSchema, Provider, ActionTypes, + getAPIKey, } diff --git a/packages/client/src/utils/api.js b/packages/client/src/utils/api.js new file mode 100644 index 0000000000..4e6025873d --- /dev/null +++ b/packages/client/src/utils/api.js @@ -0,0 +1,6 @@ +import { API } from "api" + +export const getAPIKey = async () => { + const { apiKey } = await API.fetchDeveloperInfo() + return apiKey +} diff --git a/packages/frontend-core/package.json b/packages/frontend-core/package.json index 607d817c75..ed751423db 100644 --- a/packages/frontend-core/package.json +++ b/packages/frontend-core/package.json @@ -1,12 +1,12 @@ { "name": "@budibase/frontend-core", - "version": "1.4.17", + "version": "1.4.18-alpha.0", "description": "Budibase frontend core libraries used in builder and client", "author": "Budibase", "license": "MPL-2.0", "svelte": "src/index.js", "dependencies": { - "@budibase/bbui": "^1.4.17", + "@budibase/bbui": "1.4.18-alpha.0", "lodash": "^4.17.21", "svelte": "^3.46.2" } diff --git a/packages/frontend-core/src/api/groups.js b/packages/frontend-core/src/api/groups.js index ce0c8e7729..c27f11e0ea 100644 --- a/packages/frontend-core/src/api/groups.js +++ b/packages/frontend-core/src/api/groups.js @@ -1,40 +1,91 @@ -export const buildGroupsEndpoints = API => ({ - /** - * Creates a user group. - * @param user the new group to create - */ - saveGroup: async group => { +export const buildGroupsEndpoints = API => { + // underlying functionality of adding/removing users/apps to groups + async function updateGroupResource(groupId, resource, operation, ids) { + if (!Array.isArray(ids)) { + ids = [ids] + } return await API.post({ - url: "/api/global/groups", - body: group, + url: `/api/global/groups/${groupId}/${resource}`, + body: { + [operation]: ids, + }, }) - }, - /** - * Gets all of the user groups - */ - getGroups: async () => { - return await API.get({ - url: "/api/global/groups", - }) - }, + } - /** - * Gets a group by ID - */ - getGroup: async id => { - return await API.get({ - url: `/api/global/groups/${id}`, - }) - }, + return { + /** + * Creates a user group. + * @param group the new group to create + */ + saveGroup: async group => { + return await API.post({ + url: "/api/global/groups", + body: group, + }) + }, + /** + * Gets all the user groups + */ + getGroups: async () => { + return await API.get({ + url: "/api/global/groups", + }) + }, - /** - * Deletes a user group - * @param id the id of the config to delete - * @param rev the revision of the config to delete - */ - deleteGroup: async ({ id, rev }) => { - return await API.delete({ - url: `/api/global/groups/${id}/${rev}`, - }) - }, -}) + /** + * Gets a group by ID + */ + getGroup: async id => { + return await API.get({ + url: `/api/global/groups/${id}`, + }) + }, + + /** + * Deletes a user group + * @param id the id of the config to delete + * @param rev the revision of the config to delete + */ + deleteGroup: async ({ id, rev }) => { + return await API.delete({ + url: `/api/global/groups/${id}/${rev}`, + }) + }, + + /** + * Adds users to a group + * @param groupId The group to update + * @param userIds The user IDs to be added + */ + addUsersToGroup: async (groupId, userIds) => { + return updateGroupResource(groupId, "users", "add", userIds) + }, + + /** + * Removes users from a group + * @param groupId The group to update + * @param userIds The user IDs to be removed + */ + removeUsersFromGroup: async (groupId, userIds) => { + return updateGroupResource(groupId, "users", "remove", userIds) + }, + + /** + * Adds apps to a group + * @param groupId The group to update + * @param appArray Array of objects, containing the appId and roleId to be added + */ + addAppsToGroup: async (groupId, appArray) => { + return updateGroupResource(groupId, "apps", "add", appArray) + }, + + /** + * Removes apps from a group + * @param groupId The group to update + * @param appArray Array of objects, containing the appId to be removed + */ + removeAppsFromGroup: async (groupId, appArray) => { + return updateGroupResource(groupId, "apps", "remove", appArray) + }, + } +} diff --git a/packages/frontend-core/src/api/licensing.js b/packages/frontend-core/src/api/licensing.js index 16d65a20d7..c27d79d740 100644 --- a/packages/frontend-core/src/api/licensing.js +++ b/packages/frontend-core/src/api/licensing.js @@ -9,6 +9,15 @@ export const buildLicensingEndpoints = API => ({ }) }, + /** + * Delete a self hosted license key + */ + deleteLicenseKey: async () => { + return API.delete({ + url: `/api/global/license/info`, + }) + }, + /** * Get the license info - metadata about the license including the * obfuscated license key. diff --git a/packages/frontend-core/src/api/user.js b/packages/frontend-core/src/api/user.js index 653376aa55..39d9359e91 100644 --- a/packages/frontend-core/src/api/user.js +++ b/packages/frontend-core/src/api/user.js @@ -86,15 +86,19 @@ export const buildUserEndpoints = API => ({ /** * Creates multiple users. * @param users the array of user objects to create + * @param groups the array of group ids to add all users to */ createUsers: async ({ users, groups }) => { - return await API.post({ - url: "/api/global/users/bulkCreate", + const res = await API.post({ + url: "/api/global/users/bulk", body: { - users, - groups, + create: { + users, + groups, + }, }, }) + return res.created }, /** @@ -109,15 +113,18 @@ export const buildUserEndpoints = API => ({ /** * Deletes multiple users - * @param userId the ID of the user to delete + * @param userIds the ID of the user to delete */ deleteUsers: async userIds => { - return await API.post({ - url: `/api/global/users/bulkDelete`, + const res = await API.post({ + url: `/api/global/users/bulk`, body: { - userIds, + delete: { + userIds, + }, }, }) + return res.deleted }, /** @@ -151,6 +158,7 @@ export const buildUserEndpoints = API => ({ userInfo: { admin: user.admin ? { global: true } : undefined, builder: user.admin || user.builder ? { global: true } : undefined, + groups: user.groups, }, })), }) diff --git a/packages/frontend-core/src/fetch/DataFetch.js b/packages/frontend-core/src/fetch/DataFetch.js index 345e58ac42..a3cc1c231c 100644 --- a/packages/frontend-core/src/fetch/DataFetch.js +++ b/packages/frontend-core/src/fetch/DataFetch.js @@ -156,6 +156,8 @@ export default class DataFetch { schema, query, loading: true, + cursors: [], + cursor: null, })) // Actually fetch data diff --git a/packages/frontend-core/src/fetch/UserFetch.js b/packages/frontend-core/src/fetch/UserFetch.js new file mode 100644 index 0000000000..9aeadbc0f5 --- /dev/null +++ b/packages/frontend-core/src/fetch/UserFetch.js @@ -0,0 +1,52 @@ +import { get } from "svelte/store" +import DataFetch from "./DataFetch.js" +import { TableNames } from "../constants" + +export default class UserFetch extends DataFetch { + constructor(opts) { + super({ + ...opts, + datasource: { + tableId: TableNames.USERS, + }, + }) + } + + determineFeatureFlags() { + return { + supportsSearch: true, + supportsSort: false, + supportsPagination: true, + } + } + + async getDefinition() { + return { + schema: {}, + } + } + + async getData() { + const { cursor, query } = get(this.store) + try { + // "query" normally contains a lucene query, but users uses a non-standard + // search endpoint so we use query uniquely here + const res = await this.API.searchUsers({ + page: cursor, + email: query.email, + appId: query.appId, + }) + return { + rows: res?.data || [], + hasNextPage: res?.hasNextPage || false, + cursor: res?.nextPage || null, + } + } catch (error) { + return { + rows: [], + hasNextPage: false, + error, + } + } + } +} diff --git a/packages/frontend-core/src/fetch/fetchData.js b/packages/frontend-core/src/fetch/fetchData.js index e914ff863f..4974816496 100644 --- a/packages/frontend-core/src/fetch/fetchData.js +++ b/packages/frontend-core/src/fetch/fetchData.js @@ -5,12 +5,14 @@ import RelationshipFetch from "./RelationshipFetch.js" import NestedProviderFetch from "./NestedProviderFetch.js" import FieldFetch from "./FieldFetch.js" import JSONArrayFetch from "./JSONArrayFetch.js" +import UserFetch from "./UserFetch.js" const DataFetchMap = { table: TableFetch, view: ViewFetch, query: QueryFetch, link: RelationshipFetch, + user: UserFetch, // Client specific datasource types provider: NestedProviderFetch, diff --git a/packages/frontend-core/src/themes/nord.css b/packages/frontend-core/src/themes/nord.css index c5a9b13640..11c7a3aea1 100644 --- a/packages/frontend-core/src/themes/nord.css +++ b/packages/frontend-core/src/themes/nord.css @@ -28,6 +28,7 @@ --spectrum-global-color-static-blue-600: #5680b4; --spectrum-global-color-static-blue-700: #4e79af; --spectrum-global-color-static-blue-800: #4a73a6; + --spectrum-global-color-static-blue: var(--spectrum-global-color-blue-600); --spectrum-global-color-gray-50: #2e3440; --spectrum-global-color-gray-75: #353b4a; diff --git a/packages/frontend-core/src/utils/utils.js b/packages/frontend-core/src/utils/utils.js index 71688981a9..587d057351 100644 --- a/packages/frontend-core/src/utils/utils.js +++ b/packages/frontend-core/src/utils/utils.js @@ -19,3 +19,24 @@ export const sequential = fn => { } } } + +/** + * Utility to debounce an async function and ensure a minimum delay between + * invocations is enforced. + * @param callback an async function to run + * @param minDelay the minimum delay between invocations + * @returns {Promise} a debounced version of the callback + */ +export const debounce = (callback, minDelay = 1000) => { + let timeout + return async (...params) => { + return new Promise(resolve => { + if (timeout) { + clearTimeout(timeout) + } + timeout = setTimeout(async () => { + resolve(await callback(...params)) + }, minDelay) + }) + } +} diff --git a/packages/sdk/.gitignore b/packages/sdk/.gitignore new file mode 100644 index 0000000000..43e879ac90 --- /dev/null +++ b/packages/sdk/.gitignore @@ -0,0 +1,4 @@ +sdk +docs +node_modules +dist \ No newline at end of file diff --git a/packages/sdk/README.md b/packages/sdk/README.md new file mode 100644 index 0000000000..64b4c0538d --- /dev/null +++ b/packages/sdk/README.md @@ -0,0 +1,33 @@ +# Budibase Public API SDK +JS SDK for the Budibase Public API. + +This SDK is generated by [swagger-codegen](https://github.com/swagger-api/swagger-codegen). + +Docker is used to run the generator, so Java is not required. Docker is the only requirement to generate the SDK. + +The generated code will only run in a browser. It is not currently useable in a NodeJS environment. + +## Example usage +```js +import { configure, ApplicationsApi } from "@budibase/sdk" + +// Configure the API client +configure({ + apiKey: "my-api-key", + host: "https://my.budibase.app" +}) + +// Search for an app. +// We can use the promisified version... +const res = await ApplicationsApi.applicationsSearchPost({ name: "foo" }) +console.log("Applications:", res.data) + +// ...or the callback version +ApplicationsApi.applicationsSearchPost({ name: "foo" }, ((error, data) => { + if (error) { + console.error("Failed to search:", error) + } else { + console.log("Applications:", data.data) + } +})) +``` \ No newline at end of file diff --git a/packages/sdk/package.json b/packages/sdk/package.json new file mode 100644 index 0000000000..b37b5a5d9e --- /dev/null +++ b/packages/sdk/package.json @@ -0,0 +1,23 @@ +{ + "name": "@budibase/sdk", + "version": "1.4.18-alpha.0", + "description": "Budibase Public API SDK", + "author": "Budibase", + "license": "MPL-2.0", + "module": "dist/sdk.mjs", + "type": "module", + "scripts": { + "generate": "cd scripts && bash generate-sdk.sh", + "build:sdk": "yarn run generate && rollup -c" + }, + "dependencies": { + "superagent": "^5.3.0" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^18.0.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "rollup": "^2.44.0", + "rollup-plugin-polyfill-node": "^0.8.0", + "rollup-plugin-terser": "^7.0.2" + } +} diff --git a/packages/sdk/rollup.config.js b/packages/sdk/rollup.config.js new file mode 100644 index 0000000000..b9c1543c42 --- /dev/null +++ b/packages/sdk/rollup.config.js @@ -0,0 +1,22 @@ +import commonjs from "@rollup/plugin-commonjs" +import resolve from "@rollup/plugin-node-resolve" +import nodePolyfills from "rollup-plugin-polyfill-node" + +export default { + input: "src/index.js", + output: [ + { + sourcemap: false, + format: "esm", + file: "./dist/sdk.mjs", + }, + ], + plugins: [ + commonjs(), + nodePolyfills(), + resolve({ + preferBuiltins: true, + browser: true, + }), + ], +} diff --git a/packages/sdk/scripts/config.json b/packages/sdk/scripts/config.json new file mode 100644 index 0000000000..a6a3e1acb8 --- /dev/null +++ b/packages/sdk/scripts/config.json @@ -0,0 +1,3 @@ +{ + "usePromises": true +} \ No newline at end of file diff --git a/packages/sdk/scripts/generate-sdk.sh b/packages/sdk/scripts/generate-sdk.sh new file mode 100755 index 0000000000..82cb3f1d36 --- /dev/null +++ b/packages/sdk/scripts/generate-sdk.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Cleanup +if [[ -f "openapi.yaml" ]]; then + rm openapi.yaml +fi +if [[ -d "generated" ]]; then + rm -r generated +fi +if [[ -d "../sdk" ]]; then + rm -r ../sdk +fi + +# Generate new SDK +mkdir generated +cp ../../server/specs/openapi.yaml ./ +docker run --rm \ + -v ${PWD}/openapi.yaml:/openapi.yml \ + -v ${PWD}/generated:/generated \ + -v ${PWD}/config.json:/config.json \ + -u $(id -u):$(id -g) \ + swaggerapi/swagger-codegen-cli-v3 generate \ + -i /openapi.yml \ + -l javascript \ + -o /generated \ + -c /config.json + +# Use a subset of the generated files +mv generated/src ../sdk + +# Cleanup +if [[ -f "openapi.yaml" ]]; then + rm openapi.yaml +fi +if [[ -d "generated" ]]; then + rm -r generated +fi \ No newline at end of file diff --git a/packages/sdk/src/index.js b/packages/sdk/src/index.js new file mode 100644 index 0000000000..4569907702 --- /dev/null +++ b/packages/sdk/src/index.js @@ -0,0 +1,23 @@ +import * as BudibaseApi from "../sdk" + +export default class SDK { + applications = new BudibaseApi.ApplicationsApi() + queries = new BudibaseApi.QueriesApi() + rows = new BudibaseApi.RowsApi() + tables = new BudibaseApi.TablesApi() + users = new BudibaseApi.UsersApi() + + constructor({ apiKey, host }) { + let ApiClient = new BudibaseApi.ApiClient() + + // Default to current host + ApiClient.basePath = `${host || ""}/api/public/v1` + ApiClient.authentications["ApiKeyAuth"].apiKey = apiKey + + this.applications = new BudibaseApi.ApplicationsApi(ApiClient) + this.queries = new BudibaseApi.QueriesApi(ApiClient) + this.rows = new BudibaseApi.RowsApi(ApiClient) + this.tables = new BudibaseApi.TablesApi(ApiClient) + this.users = new BudibaseApi.UsersApi(ApiClient) + } +} diff --git a/packages/sdk/yarn.lock b/packages/sdk/yarn.lock new file mode 100644 index 0000000000..4e8d6d718f --- /dev/null +++ b/packages/sdk/yarn.lock @@ -0,0 +1,635 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.10.4": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== + dependencies: + "@babel/highlight" "^7.18.6" + +"@babel/helper-validator-identifier@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" + integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== + +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@jridgewell/gen-mapping@^0.3.0": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" + integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.9": + version "0.3.15" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" + integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@rollup/plugin-commonjs@^18.0.0": + version "18.1.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-18.1.0.tgz#5a760d757af168a50727c0ae080251fbfcc5eb02" + integrity sha512-h3e6T9rUxVMAQswpDIobfUHn/doMzM9sgkMrsMWCFLmB84PSoC8mV8tOloAJjSRwdqhXBqstlX2BwBpHJvbhxg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + commondir "^1.0.1" + estree-walker "^2.0.1" + glob "^7.1.6" + is-reference "^1.2.1" + magic-string "^0.25.7" + resolve "^1.17.0" + +"@rollup/plugin-inject@^4.0.0": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@rollup/plugin-inject/-/plugin-inject-4.0.4.tgz#fbeee66e9a700782c4f65c8b0edbafe58678fbc2" + integrity sha512-4pbcU4J/nS+zuHk+c+OL3WtmEQhqxlZ9uqfjQMQDOHOPld7PsCd8k5LWs8h5wjwJN7MgnAn768F2sDxEP4eNFQ== + dependencies: + "@rollup/pluginutils" "^3.1.0" + estree-walker "^2.0.1" + magic-string "^0.25.7" + +"@rollup/plugin-node-resolve@^11.2.1": + version "11.2.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz#82aa59397a29cd4e13248b106e6a4a1880362a60" + integrity sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + "@types/resolve" "1.17.1" + builtin-modules "^3.1.0" + deepmerge "^4.2.2" + is-module "^1.0.0" + resolve "^1.19.0" + +"@rollup/pluginutils@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" + integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== + dependencies: + "@types/estree" "0.0.39" + estree-walker "^1.0.1" + picomatch "^2.2.2" + +"@types/estree@*": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" + integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== + +"@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + +"@types/node@*": + version "18.7.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.18.tgz#633184f55c322e4fb08612307c274ee6d5ed3154" + integrity sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg== + +"@types/resolve@1.17.1": + version "1.17.1" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" + integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== + dependencies: + "@types/node" "*" + +acorn@^8.5.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +builtin-modules@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" + integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== + +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + +component-emitter@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +cookiejar@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.3.tgz#fc7a6216e408e74414b90230050842dacda75acc" + integrity sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ== + +debug@^4.1.1: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +estree-walker@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" + integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== + +estree-walker@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + +fast-safe-stringify@^2.0.7: + version "2.1.1" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" + integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== + +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +formidable@^1.2.2: + version "1.2.6" + resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.6.tgz#d2a51d60162bbc9b4a055d8457a7c75315d1a168" + integrity sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-intrinsic@^1.0.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" + integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +glob@^7.1.6: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-core-module@^2.9.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" + integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== + dependencies: + has "^1.0.3" + +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== + +is-reference@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" + integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== + dependencies: + "@types/estree" "*" + +jest-worker@^26.2.1: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +magic-string@^0.25.7: + version "0.25.9" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" + integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== + dependencies: + sourcemap-codec "^1.4.8" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +methods@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@^2.4.6: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +object-inspect@^1.9.0: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +picomatch@^2.2.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +qs@^6.9.4: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +resolve@^1.17.0, resolve@^1.19.0: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +rollup-plugin-polyfill-node@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-polyfill-node/-/rollup-plugin-polyfill-node-0.8.0.tgz#859c070822f5e38d221e5b4238cb34aa894c2b19" + integrity sha512-C4UeKedOmOBkB3FgR+z/v9kzRwV1Q/H8xWs1u1+CNe4XOV6hINfOrcO+TredKxYvopCmr+WKUSNsFUnD1RLHgQ== + dependencies: + "@rollup/plugin-inject" "^4.0.0" + +rollup-plugin-terser@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" + integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== + dependencies: + "@babel/code-frame" "^7.10.4" + jest-worker "^26.2.1" + serialize-javascript "^4.0.0" + terser "^5.0.0" + +rollup@^2.44.0: + version "2.79.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.0.tgz#9177992c9f09eb58c5e56cbfa641607a12b57ce2" + integrity sha512-x4KsrCgwQ7ZJPcFA/SUu6QVcYlO7uRLfLAy0DSA4NS2eG8japdbpM50ToH7z4iObodRYOJ0soneF0iaQRJ6zhA== + optionalDependencies: + fsevents "~2.3.2" + +safe-buffer@^5.1.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +semver@^7.3.2: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + +serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sourcemap-codec@^1.4.8: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +superagent@^5.3.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-5.3.1.tgz#d62f3234d76b8138c1320e90fa83dc1850ccabf1" + integrity sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ== + dependencies: + component-emitter "^1.3.0" + cookiejar "^2.1.2" + debug "^4.1.1" + fast-safe-stringify "^2.0.7" + form-data "^3.0.0" + formidable "^1.2.2" + methods "^1.1.2" + mime "^2.4.6" + qs "^6.9.4" + readable-stream "^3.6.0" + semver "^7.3.2" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.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== + dependencies: + has-flag "^4.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" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +terser@^5.0.0: + version "5.15.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.15.0.tgz#e16967894eeba6e1091509ec83f0c60e179f2425" + integrity sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA== + dependencies: + "@jridgewell/source-map" "^0.3.2" + acorn "^8.5.0" + commander "^2.20.0" + source-map-support "~0.5.20" + +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/packages/server/Dockerfile b/packages/server/Dockerfile index bd01b6f9ff..b55bde7906 100644 --- a/packages/server/Dockerfile +++ b/packages/server/Dockerfile @@ -12,6 +12,8 @@ ENV COUCH_DB_URL=https://couchdb.budi.live:5984 ENV BUDIBASE_ENVIRONMENT=PRODUCTION ENV SERVICE=app-service ENV POSTHOG_TOKEN=phc_bIjZL7oh2GEUd2vqvTBH8WvrX0fWTFQMs6H5KQxiUxU +ENV TENANT_FEATURE_FLAGS=*:LICENSING,*:USER_GROUPS +ENV ACCOUNT_PORTAL_URL=https://account.budibase.app # copy files and install dependencies COPY . ./ diff --git a/packages/server/package.json b/packages/server/package.json index f55b352fe8..4681691f42 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "1.4.17", + "version": "1.4.18-alpha.0", "description": "Budibase Web Server", "main": "src/index.ts", "repository": { @@ -77,11 +77,11 @@ "license": "GPL-3.0", "dependencies": { "@apidevtools/swagger-parser": "10.0.3", - "@budibase/backend-core": "^1.4.17", - "@budibase/client": "^1.4.17", - "@budibase/pro": "1.4.17", - "@budibase/string-templates": "^1.4.17", - "@budibase/types": "^1.4.17", + "@budibase/backend-core": "1.4.18-alpha.0", + "@budibase/client": "1.4.18-alpha.0", + "@budibase/pro": "1.4.18-alpha.0", + "@budibase/string-templates": "1.4.18-alpha.0", + "@budibase/types": "1.4.18-alpha.0", "@bull-board/api": "3.7.0", "@bull-board/koa": "3.9.4", "@elastic/elasticsearch": "7.10.0", diff --git a/packages/server/scripts/dev/manage.js b/packages/server/scripts/dev/manage.js index ac04780ada..e06c6308f8 100644 --- a/packages/server/scripts/dev/manage.js +++ b/packages/server/scripts/dev/manage.js @@ -59,6 +59,7 @@ async function init() { BB_ADMIN_USER_EMAIL: "", BB_ADMIN_USER_PASSWORD: "", PLUGINS_DIR: "", + TENANT_FEATURE_FLAGS: "*:LICENSING,*:USER_GROUPS", } let envFile = "" Object.keys(envFileJson).forEach(key => { diff --git a/packages/server/specs/openapi.json b/packages/server/specs/openapi.json index f8539b9f7f..ce410823ec 100644 --- a/packages/server/specs/openapi.json +++ b/packages/server/specs/openapi.json @@ -1792,6 +1792,7 @@ "paths": { "/applications": { "post": { + "operationId": "create", "summary": "Create an application", "tags": [ "applications" @@ -1832,6 +1833,7 @@ }, "/applications/{appId}": { "put": { + "operationId": "update", "summary": "Update an application", "tags": [ "applications" @@ -1870,6 +1872,7 @@ } }, "delete": { + "operationId": "destroy", "summary": "Delete an application", "tags": [ "applications" @@ -1898,6 +1901,7 @@ } }, "get": { + "operationId": "getById", "summary": "Retrieve an application", "tags": [ "applications" @@ -1928,6 +1932,7 @@ }, "/applications/search": { "post": { + "operationId": "search", "summary": "Search for applications", "description": "Based on application properties (currently only name) search for applications.", "tags": [ @@ -1964,6 +1969,7 @@ }, "/queries/{queryId}": { "post": { + "operationId": "execute", "summary": "Execute a query", "description": "Queries which have been created within a Budibase app can be executed using this,", "tags": [ @@ -2011,6 +2017,7 @@ }, "/queries/search": { "post": { + "operationId": "search", "summary": "Search for queries", "description": "Based on query properties (currently only name) search for queries.", "tags": [ @@ -2052,6 +2059,7 @@ }, "/tables/{tableId}/rows": { "post": { + "operationId": "create", "summary": "Create a row", "description": "Creates a row within the specified table.", "tags": [ @@ -2101,6 +2109,7 @@ }, "/tables/{tableId}/rows/{rowId}": { "put": { + "operationId": "update", "summary": "Update a row", "description": "Updates a row within the specified table.", "tags": [ @@ -2151,6 +2160,7 @@ } }, "delete": { + "operationId": "destroy", "summary": "Delete a row", "description": "Deletes a row within the specified table.", "tags": [ @@ -2186,6 +2196,7 @@ } }, "get": { + "operationId": "getById", "summary": "Retrieve a row", "description": "This gets a single row, it will be enriched with the full related rows, rather than the squashed \"primaryDisplay\" format returned by the search endpoint.", "tags": [ @@ -2223,6 +2234,7 @@ }, "/tables/{tableId}/rows/search": { "post": { + "operationId": "search", "summary": "Search for rows", "tags": [ "rows" @@ -2266,6 +2278,7 @@ }, "/tables": { "post": { + "operationId": "create", "summary": "Create a table", "description": "Create a table, this could be internal or external.", "tags": [ @@ -2311,6 +2324,7 @@ }, "/tables/{tableId}": { "put": { + "operationId": "update", "summary": "Update a table", "description": "Update a table, this could be internal or external.", "tags": [ @@ -2357,6 +2371,7 @@ } }, "delete": { + "operationId": "destroy", "summary": "Delete a table", "description": "Delete a table, this could be internal or external.", "tags": [ @@ -2389,6 +2404,7 @@ } }, "get": { + "operationId": "getById", "summary": "Retrieve a table", "description": "Lookup a table, this could be internal or external.", "tags": [ @@ -2423,6 +2439,7 @@ }, "/tables/search": { "post": { + "operationId": "search", "summary": "Search for tables", "description": "Based on table properties (currently only name) search for tables. This could be an internal or an external table.", "tags": [ @@ -2464,6 +2481,7 @@ }, "/users": { "post": { + "operationId": "create", "summary": "Create a user", "tags": [ "users" @@ -2499,6 +2517,7 @@ }, "/users/{userId}": { "put": { + "operationId": "update", "summary": "Update a user", "tags": [ "users" @@ -2537,6 +2556,7 @@ } }, "delete": { + "operationId": "destroy", "summary": "Delete a user", "tags": [ "users" @@ -2565,6 +2585,7 @@ } }, "get": { + "operationId": "getById", "summary": "Retrieve a user", "tags": [ "users" @@ -2595,6 +2616,7 @@ }, "/users/search": { "post": { + "operationId": "search", "summary": "Search for users", "description": "Based on user properties (currently only name) search for users.", "tags": [ diff --git a/packages/server/specs/openapi.yaml b/packages/server/specs/openapi.yaml index 3cd29791af..ed13ac01f4 100644 --- a/packages/server/specs/openapi.yaml +++ b/packages/server/specs/openapi.yaml @@ -1370,6 +1370,7 @@ security: paths: /applications: post: + operationId: create summary: Create an application tags: - applications @@ -1393,6 +1394,7 @@ paths: $ref: "#/components/examples/application" "/applications/{appId}": put: + operationId: update summary: Update an application tags: - applications @@ -1415,6 +1417,7 @@ paths: application: $ref: "#/components/examples/application" delete: + operationId: destroy summary: Delete an application tags: - applications @@ -1431,6 +1434,7 @@ paths: application: $ref: "#/components/examples/application" get: + operationId: getById summary: Retrieve an application tags: - applications @@ -1448,6 +1452,7 @@ paths: $ref: "#/components/examples/application" /applications/search: post: + operationId: search summary: Search for applications description: Based on application properties (currently only name) search for applications. @@ -1472,6 +1477,7 @@ paths: $ref: "#/components/examples/applications" "/queries/{queryId}": post: + operationId: execute summary: Execute a query description: Queries which have been created within a Budibase app can be executed using this, @@ -1500,6 +1506,7 @@ paths: $ref: "#/components/examples/sqlResponse" /queries/search: post: + operationId: search summary: Search for queries description: Based on query properties (currently only name) search for queries. tags: @@ -1524,6 +1531,7 @@ paths: $ref: "#/components/examples/queries" "/tables/{tableId}/rows": post: + operationId: create summary: Create a row description: Creates a row within the specified table. tags: @@ -1554,6 +1562,7 @@ paths: $ref: "#/components/examples/row" "/tables/{tableId}/rows/{rowId}": put: + operationId: update summary: Update a row description: Updates a row within the specified table. tags: @@ -1583,6 +1592,7 @@ paths: row: $ref: "#/components/examples/row" delete: + operationId: destroy summary: Delete a row description: Deletes a row within the specified table. tags: @@ -1603,6 +1613,7 @@ paths: row: $ref: "#/components/examples/row" get: + operationId: getById summary: Retrieve a row description: This gets a single row, it will be enriched with the full related rows, rather than the squashed "primaryDisplay" format returned by the @@ -1625,6 +1636,7 @@ paths: $ref: "#/components/examples/enrichedRow" "/tables/{tableId}/rows/search": post: + operationId: search summary: Search for rows tags: - rows @@ -1650,6 +1662,7 @@ paths: $ref: "#/components/examples/rows" /tables: post: + operationId: create summary: Create a table description: Create a table, this could be internal or external. tags: @@ -1677,6 +1690,7 @@ paths: $ref: "#/components/examples/table" "/tables/{tableId}": put: + operationId: update summary: Update a table description: Update a table, this could be internal or external. tags: @@ -1703,6 +1717,7 @@ paths: table: $ref: "#/components/examples/table" delete: + operationId: destroy summary: Delete a table description: Delete a table, this could be internal or external. tags: @@ -1721,6 +1736,7 @@ paths: table: $ref: "#/components/examples/table" get: + operationId: getById summary: Retrieve a table description: Lookup a table, this could be internal or external. tags: @@ -1740,6 +1756,7 @@ paths: $ref: "#/components/examples/table" /tables/search: post: + operationId: search summary: Search for tables description: Based on table properties (currently only name) search for tables. This could be an internal or an external table. @@ -1765,6 +1782,7 @@ paths: $ref: "#/components/examples/tables" /users: post: + operationId: create summary: Create a user tags: - users @@ -1786,6 +1804,7 @@ paths: $ref: "#/components/examples/user" "/users/{userId}": put: + operationId: update summary: Update a user tags: - users @@ -1808,6 +1827,7 @@ paths: user: $ref: "#/components/examples/user" delete: + operationId: destroy summary: Delete a user tags: - users @@ -1824,6 +1844,7 @@ paths: user: $ref: "#/components/examples/user" get: + operationId: getById summary: Retrieve a user tags: - users @@ -1841,6 +1862,7 @@ paths: $ref: "#/components/examples/user" /users/search: post: + operationId: search summary: Search for users description: Based on user properties (currently only name) search for users. tags: diff --git a/packages/server/src/api/controllers/application.ts b/packages/server/src/api/controllers/application.ts index 56054d1b58..6771f7e4e0 100644 --- a/packages/server/src/api/controllers/application.ts +++ b/packages/server/src/api/controllers/application.ts @@ -47,14 +47,9 @@ import { checkAppMetadata } from "../../automations/logging" import { getUniqueRows } from "../../utilities/usageQuota/rows" import { quotas } from "@budibase/pro" import { errors, events, migrations } from "@budibase/backend-core" -import { - App, - Layout, - Screen, - MigrationType, - AppNavigation, -} from "@budibase/types" +import { App, Layout, Screen, MigrationType } from "@budibase/types" import { BASE_LAYOUT_PROP_IDS } from "../../constants/layouts" +import { groups } from "@budibase/pro" const URL_REGEX_SLASH = /\/|\\/g @@ -501,6 +496,7 @@ const preDestroyApp = async (ctx: any) => { const postDestroyApp = async (ctx: any) => { const rowCount = ctx.rowCount + await groups.cleanupApp(ctx.params.appId) if (rowCount) { await quotas.removeRows(rowCount) } diff --git a/packages/server/src/api/controllers/auth.js b/packages/server/src/api/controllers/auth.ts similarity index 59% rename from packages/server/src/api/controllers/auth.js rename to packages/server/src/api/controllers/auth.ts index 51ce737c41..ef2cb29385 100644 --- a/packages/server/src/api/controllers/auth.js +++ b/packages/server/src/api/controllers/auth.ts @@ -1,19 +1,21 @@ -const { outputProcessing } = require("../../utilities/rowProcessor") -const { InternalTables } = require("../../db/utils") -const { getFullUser } = require("../../utilities/users") -const { BUILTIN_ROLE_IDS } = require("@budibase/backend-core/roles") -const { getAppDB, getAppId } = require("@budibase/backend-core/context") +import { outputProcessing } from "../../utilities/rowProcessor" +import { InternalTables } from "../../db/utils" +import { getFullUser } from "../../utilities/users" +import { roles, context } from "@budibase/backend-core" +import { groups } from "@budibase/pro" + +const PUBLIC_ROLE = roles.BUILTIN_ROLE_IDS.PUBLIC /** * Add the attributes that are session based to the current user. */ -const addSessionAttributesToUser = ctx => { +const addSessionAttributesToUser = (ctx: any) => { if (ctx.user) { ctx.body.license = ctx.user.license } } -exports.fetchSelf = async ctx => { +export async function fetchSelf(ctx: any) { let userId = ctx.user.userId || ctx.user._id /* istanbul ignore next */ if (!userId || !ctx.isAuthenticated) { @@ -21,30 +23,30 @@ exports.fetchSelf = async ctx => { return } + const appId = context.getAppId() const user = await getFullUser(ctx, userId) // this shouldn't be returned by the app self delete user.roles // forward the csrf token from the session user.csrfToken = ctx.user.csrfToken - if (getAppId()) { - const db = getAppDB() + if (appId) { + const db = context.getAppDB() + // check for group permissions + if (!user.roleId || user.roleId === PUBLIC_ROLE) { + const groupRoleId = await groups.getGroupRoleId(user, appId) + user.roleId = groupRoleId || user.roleId + } // remove the full roles structure delete user.roles try { const userTable = await db.get(InternalTables.USER_METADATA) - const metadata = await db.get(userId) - // make sure there is never a stale csrf token - delete metadata.csrfToken // specifically needs to make sure is enriched - ctx.body = await outputProcessing(userTable, { - ...user, - ...metadata, - }) - } catch (err) { + ctx.body = await outputProcessing(userTable, user) + } catch (err: any) { let response // user didn't exist in app, don't pretend they do - if (user.roleId === BUILTIN_ROLE_IDS.PUBLIC) { + if (user.roleId === PUBLIC_ROLE) { response = {} } // user has a role of some sort, return them diff --git a/packages/server/src/api/controllers/integration.js b/packages/server/src/api/controllers/integration.js index ae9be7e6fe..3d1643601b 100644 --- a/packages/server/src/api/controllers/integration.js +++ b/packages/server/src/api/controllers/integration.js @@ -8,7 +8,7 @@ exports.fetch = async function (ctx) { const defs = await getDefinitions() // for google sheets integration google verification - if (featureFlags.isEnabled(featureFlags.FeatureFlag.GOOGLE_SHEETS)) { + if (featureFlags.isEnabled(featureFlags.TenantFeatureFlag.GOOGLE_SHEETS)) { defs[SourceName.GOOGLE_SHEETS] = googlesheets.schema } diff --git a/packages/server/src/api/controllers/row/internal.js b/packages/server/src/api/controllers/row/internal.js index 0c92959db8..e59d2cb38f 100644 --- a/packages/server/src/api/controllers/row/internal.js +++ b/packages/server/src/api/controllers/row/internal.js @@ -333,7 +333,7 @@ exports.bulkDestroy = async ctx => { exports.search = async ctx => { // Fetch the whole table when running in cypress, as search doesn't work - if (env.isCypress()) { + if (!env.COUCH_DB_URL && env.isCypress()) { return { rows: await exports.fetch(ctx) } } diff --git a/packages/server/src/api/routes/analytics.js b/packages/server/src/api/routes/analytics.js index d13ace12d1..610d6d0c7f 100644 --- a/packages/server/src/api/routes/analytics.js +++ b/packages/server/src/api/routes/analytics.js @@ -1,7 +1,7 @@ const Router = require("@koa/router") const controller = require("../controllers/analytics") -const router = Router() +const router = new Router() router.get("/api/bbtel", controller.isEnabled) router.post("/api/bbtel/ping", controller.ping) diff --git a/packages/server/src/api/routes/apikeys.js b/packages/server/src/api/routes/apikeys.js index 315cffb41a..ddbd35c23c 100644 --- a/packages/server/src/api/routes/apikeys.js +++ b/packages/server/src/api/routes/apikeys.js @@ -3,7 +3,7 @@ const controller = require("../controllers/apikeys") const authorized = require("../../middleware/authorized") const { BUILDER } = require("@budibase/backend-core/permissions") -const router = Router() +const router = new Router() router .get("/api/keys", authorized(BUILDER), controller.fetch) diff --git a/packages/server/src/api/routes/auth.js b/packages/server/src/api/routes/auth.js deleted file mode 100644 index 153c86a62d..0000000000 --- a/packages/server/src/api/routes/auth.js +++ /dev/null @@ -1,8 +0,0 @@ -const Router = require("@koa/router") -const controller = require("../controllers/auth") - -const router = Router() - -router.get("/api/self", controller.fetchSelf) - -module.exports = router diff --git a/packages/server/src/api/routes/auth.ts b/packages/server/src/api/routes/auth.ts new file mode 100644 index 0000000000..8a9d11fb27 --- /dev/null +++ b/packages/server/src/api/routes/auth.ts @@ -0,0 +1,8 @@ +import Router from "@koa/router" +import * as controller from "../controllers/auth" + +const router = new Router() + +router.get("/api/self", controller.fetchSelf) + +export default router diff --git a/packages/server/src/api/routes/automation.js b/packages/server/src/api/routes/automation.js index e0f4744e1e..e30a0c1113 100644 --- a/packages/server/src/api/routes/automation.js +++ b/packages/server/src/api/routes/automation.js @@ -13,7 +13,7 @@ const { } = require("../../middleware/appInfo") const { automationValidator } = require("./utils/validators") -const router = Router() +const router = new Router() router .get( diff --git a/packages/server/src/api/routes/backup.js b/packages/server/src/api/routes/backup.js index 83387ea75a..9f3b27e95a 100644 --- a/packages/server/src/api/routes/backup.js +++ b/packages/server/src/api/routes/backup.js @@ -3,7 +3,7 @@ const controller = require("../controllers/backup") const authorized = require("../../middleware/authorized") const { BUILDER } = require("@budibase/backend-core/permissions") -const router = Router() +const router = new Router() router.get("/api/backups/export", authorized(BUILDER), controller.exportAppDump) diff --git a/packages/server/src/api/routes/cloud.js b/packages/server/src/api/routes/cloud.js index 3cee889abf..c183ffb5ba 100644 --- a/packages/server/src/api/routes/cloud.js +++ b/packages/server/src/api/routes/cloud.js @@ -3,7 +3,7 @@ const controller = require("../controllers/cloud") const authorized = require("../../middleware/authorized") const { BUILDER } = require("@budibase/backend-core/permissions") -const router = Router() +const router = new Router() router .get("/api/cloud/export", authorized(BUILDER), controller.exportApps) diff --git a/packages/server/src/api/routes/component.js b/packages/server/src/api/routes/component.js index 0f122169aa..275f58bd6c 100644 --- a/packages/server/src/api/routes/component.js +++ b/packages/server/src/api/routes/component.js @@ -3,7 +3,7 @@ const controller = require("../controllers/component") const authorized = require("../../middleware/authorized") const { BUILDER } = require("@budibase/backend-core/permissions") -const router = Router() +const router = new Router() router.get( "/api/:appId/components/definitions", diff --git a/packages/server/src/api/routes/datasource.js b/packages/server/src/api/routes/datasource.js index 21df11b55c..23a3ea9fb0 100644 --- a/packages/server/src/api/routes/datasource.js +++ b/packages/server/src/api/routes/datasource.js @@ -11,7 +11,7 @@ const { datasourceQueryValidator, } = require("./utils/validators") -const router = Router() +const router = new Router() router .get("/api/datasources", authorized(BUILDER), datasourceController.fetch) diff --git a/packages/server/src/api/routes/deploy.js b/packages/server/src/api/routes/deploy.js index 762646435a..1f6b07c6f3 100644 --- a/packages/server/src/api/routes/deploy.js +++ b/packages/server/src/api/routes/deploy.js @@ -3,7 +3,7 @@ const controller = require("../controllers/deploy") const authorized = require("../../middleware/authorized") const { BUILDER } = require("@budibase/backend-core/permissions") -const router = Router() +const router = new Router() router .get("/api/deployments", authorized(BUILDER), controller.fetchDeployments) diff --git a/packages/server/src/api/routes/dev.js b/packages/server/src/api/routes/dev.js index 165149ca8b..0103219246 100644 --- a/packages/server/src/api/routes/dev.js +++ b/packages/server/src/api/routes/dev.js @@ -4,7 +4,7 @@ const env = require("../../environment") const authorized = require("../../middleware/authorized") const { BUILDER } = require("@budibase/backend-core/permissions") -const router = Router() +const router = new Router() function redirectPath(path) { router diff --git a/packages/server/src/api/routes/integration.js b/packages/server/src/api/routes/integration.js index ebe79d978e..5469aaa27d 100644 --- a/packages/server/src/api/routes/integration.js +++ b/packages/server/src/api/routes/integration.js @@ -3,7 +3,7 @@ const controller = require("../controllers/integration") const authorized = require("../../middleware/authorized") const { BUILDER } = require("@budibase/backend-core/permissions") -const router = Router() +const router = new Router() router .get("/api/integrations", authorized(BUILDER), controller.fetch) diff --git a/packages/server/src/api/routes/layout.js b/packages/server/src/api/routes/layout.js index fa04b63402..76103f9cfc 100644 --- a/packages/server/src/api/routes/layout.js +++ b/packages/server/src/api/routes/layout.js @@ -3,7 +3,7 @@ const authorized = require("../../middleware/authorized") const { BUILDER } = require("@budibase/backend-core/permissions") const controller = require("../controllers/layout") -const router = Router() +const router = new Router() router .post("/api/layouts", authorized(BUILDER), controller.save) diff --git a/packages/server/src/api/routes/metadata.js b/packages/server/src/api/routes/metadata.js index 129e72b5e7..0c2867c45a 100644 --- a/packages/server/src/api/routes/metadata.js +++ b/packages/server/src/api/routes/metadata.js @@ -7,7 +7,7 @@ const { const authorized = require("../../middleware/authorized") const { BUILDER } = require("@budibase/backend-core/permissions") -const router = Router() +const router = new Router() router .post( diff --git a/packages/server/src/api/routes/migrations.js b/packages/server/src/api/routes/migrations.js index 01e573edb3..a40111cf25 100644 --- a/packages/server/src/api/routes/migrations.js +++ b/packages/server/src/api/routes/migrations.js @@ -1,6 +1,6 @@ const Router = require("@koa/router") const migrationsController = require("../controllers/migrations") -const router = Router() +const router = new Router() const { internalApi } = require("@budibase/backend-core/auth") router diff --git a/packages/server/src/api/routes/permission.js b/packages/server/src/api/routes/permission.js index 831b6dd004..4736769f61 100644 --- a/packages/server/src/api/routes/permission.js +++ b/packages/server/src/api/routes/permission.js @@ -4,7 +4,7 @@ const authorized = require("../../middleware/authorized") const { BUILDER } = require("@budibase/backend-core/permissions") const { permissionValidator } = require("./utils/validators") -const router = Router() +const router = new Router() router .get("/api/permission/builtin", authorized(BUILDER), controller.fetchBuiltin) diff --git a/packages/server/src/api/routes/public/applications.ts b/packages/server/src/api/routes/public/applications.ts index 05f56da7b0..93d86d2aed 100644 --- a/packages/server/src/api/routes/public/applications.ts +++ b/packages/server/src/api/routes/public/applications.ts @@ -9,6 +9,7 @@ const read = [], * @openapi * /applications: * post: + * operationId: create * summary: Create an application * tags: * - applications @@ -41,6 +42,7 @@ write.push( * @openapi * /applications/{appId}: * put: + * operationId: update * summary: Update an application * tags: * - applications @@ -73,6 +75,7 @@ write.push( * @openapi * /applications/{appId}: * delete: + * operationId: destroy * summary: Delete an application * tags: * - applications @@ -95,6 +98,7 @@ write.push(new Endpoint("delete", "/applications/:appId", controller.destroy)) * @openapi * /applications/{appId}: * get: + * operationId: getById * summary: Retrieve an application * tags: * - applications @@ -117,6 +121,7 @@ read.push(new Endpoint("get", "/applications/:appId", controller.read)) * @openapi * /applications/search: * post: + * operationId: search * summary: Search for applications * description: Based on application properties (currently only name) search for applications. * tags: diff --git a/packages/server/src/api/routes/public/queries.ts b/packages/server/src/api/routes/public/queries.ts index 9e5d73714e..dc18fb91ac 100644 --- a/packages/server/src/api/routes/public/queries.ts +++ b/packages/server/src/api/routes/public/queries.ts @@ -9,6 +9,7 @@ const read = [], * @openapi * /queries/{queryId}: * post: + * operationId: execute * summary: Execute a query * description: Queries which have been created within a Budibase app can be executed using this, * tags: @@ -42,6 +43,7 @@ write.push(new Endpoint("post", "/queries/:queryId", controller.execute)) * @openapi * /queries/search: * post: + * operationId: search * summary: Search for queries * description: Based on query properties (currently only name) search for queries. * tags: diff --git a/packages/server/src/api/routes/public/rows.ts b/packages/server/src/api/routes/public/rows.ts index 80da073e3e..9109ae76b8 100644 --- a/packages/server/src/api/routes/public/rows.ts +++ b/packages/server/src/api/routes/public/rows.ts @@ -9,6 +9,7 @@ const read = [], * @openapi * /tables/{tableId}/rows: * post: + * operationId: create * summary: Create a row * description: Creates a row within the specified table. * tags: @@ -43,6 +44,7 @@ write.push(new Endpoint("post", "/tables/:tableId/rows", controller.create)) * @openapi * /tables/{tableId}/rows/{rowId}: * put: + * operationId: update * summary: Update a row * description: Updates a row within the specified table. * tags: @@ -79,6 +81,7 @@ write.push( * @openapi * /tables/{tableId}/rows/{rowId}: * delete: + * operationId: destroy * summary: Delete a row * description: Deletes a row within the specified table. * tags: @@ -106,6 +109,7 @@ write.push( * @openapi * /tables/{tableId}/rows/{rowId}: * get: + * operationId: getById * summary: Retrieve a row * description: This gets a single row, it will be enriched with the full related rows, rather than * the squashed "primaryDisplay" format returned by the search endpoint. @@ -132,6 +136,7 @@ read.push(new Endpoint("get", "/tables/:tableId/rows/:rowId", controller.read)) * @openapi * /tables/{tableId}/rows/search: * post: + * operationId: search * summary: Search for rows * tags: * - rows diff --git a/packages/server/src/api/routes/public/tables.ts b/packages/server/src/api/routes/public/tables.ts index 7e8ce29ae3..74cd8ca3cf 100644 --- a/packages/server/src/api/routes/public/tables.ts +++ b/packages/server/src/api/routes/public/tables.ts @@ -9,6 +9,7 @@ const read = [], * @openapi * /tables: * post: + * operationId: create * summary: Create a table * description: Create a table, this could be internal or external. * tags: @@ -45,6 +46,7 @@ write.push( * @openapi * /tables/{tableId}: * put: + * operationId: update * summary: Update a table * description: Update a table, this could be internal or external. * tags: @@ -81,6 +83,7 @@ write.push( * @openapi * /tables/{tableId}: * delete: + * operationId: destroy * summary: Delete a table * description: Delete a table, this could be internal or external. * tags: @@ -105,6 +108,7 @@ write.push(new Endpoint("delete", "/tables/:tableId", controller.destroy)) * @openapi * /tables/{tableId}: * get: + * operationId: getById * summary: Retrieve a table * description: Lookup a table, this could be internal or external. * tags: @@ -129,6 +133,7 @@ read.push(new Endpoint("get", "/tables/:tableId", controller.read)) * @openapi * /tables/search: * post: + * operationId: search * summary: Search for tables * description: Based on table properties (currently only name) search for tables. This could be * an internal or an external table. diff --git a/packages/server/src/api/routes/public/users.ts b/packages/server/src/api/routes/public/users.ts index 06e17fba42..67b73f6cbe 100644 --- a/packages/server/src/api/routes/public/users.ts +++ b/packages/server/src/api/routes/public/users.ts @@ -9,6 +9,7 @@ const read = [], * @openapi * /users: * post: + * operationId: create * summary: Create a user * tags: * - users @@ -35,6 +36,7 @@ write.push(new Endpoint("post", "/users", controller.create)) * @openapi * /users/{userId}: * put: + * operationId: update * summary: Update a user * tags: * - users @@ -63,6 +65,7 @@ write.push(new Endpoint("put", "/users/:userId", controller.update)) * @openapi * /users/{userId}: * delete: + * operationId: destroy * summary: Delete a user * tags: * - users @@ -85,6 +88,7 @@ write.push(new Endpoint("delete", "/users/:userId", controller.destroy)) * @openapi * /users/{userId}: * get: + * operationId: getById * summary: Retrieve a user * tags: * - users @@ -107,6 +111,7 @@ read.push(new Endpoint("get", "/users/:userId", controller.read)) * @openapi * /users/search: * post: + * operationId: search * summary: Search for users * description: Based on user properties (currently only name) search for users. * tags: diff --git a/packages/server/src/api/routes/query.js b/packages/server/src/api/routes/query.js index 37a26f6808..14434a45c7 100644 --- a/packages/server/src/api/routes/query.js +++ b/packages/server/src/api/routes/query.js @@ -16,7 +16,7 @@ const { generateQueryValidation, } = require("../controllers/query/validation") -const router = Router() +const router = new Router() router .get("/api/queries", authorized(BUILDER), queryController.fetch) diff --git a/packages/server/src/api/routes/role.js b/packages/server/src/api/routes/role.js index 107d9ec583..a6e04e81fa 100644 --- a/packages/server/src/api/routes/role.js +++ b/packages/server/src/api/routes/role.js @@ -4,7 +4,7 @@ const authorized = require("../../middleware/authorized") const { BUILDER } = require("@budibase/backend-core/permissions") const { roleValidator } = require("./utils/validators") -const router = Router() +const router = new Router() router .post("/api/roles", authorized(BUILDER), roleValidator(), controller.save) diff --git a/packages/server/src/api/routes/routing.js b/packages/server/src/api/routes/routing.js index 45ccb7bb64..d7e971d507 100644 --- a/packages/server/src/api/routes/routing.js +++ b/packages/server/src/api/routes/routing.js @@ -3,7 +3,7 @@ const authorized = require("../../middleware/authorized") const { BUILDER } = require("@budibase/backend-core/permissions") const controller = require("../controllers/routing") -const router = Router() +const router = new Router() router // gets correct structure for user role diff --git a/packages/server/src/api/routes/screen.js b/packages/server/src/api/routes/screen.js index e33a026126..426b89fd0f 100644 --- a/packages/server/src/api/routes/screen.js +++ b/packages/server/src/api/routes/screen.js @@ -4,7 +4,7 @@ const authorized = require("../../middleware/authorized") const { BUILDER } = require("@budibase/backend-core/permissions") const { screenValidator } = require("./utils/validators") -const router = Router() +const router = new Router() router .get("/api/screens", authorized(BUILDER), controller.fetch) diff --git a/packages/server/src/api/routes/script.js b/packages/server/src/api/routes/script.js index d0d3214db3..a4b4e4a7f5 100644 --- a/packages/server/src/api/routes/script.js +++ b/packages/server/src/api/routes/script.js @@ -3,7 +3,7 @@ const controller = require("../controllers/script") const authorized = require("../../middleware/authorized") const { BUILDER } = require("@budibase/backend-core/permissions") -const router = Router() +const router = new Router() router.post("/api/script", authorized(BUILDER), controller.save) diff --git a/packages/server/src/api/routes/table.js b/packages/server/src/api/routes/table.js index 9de36cac72..711312149a 100644 --- a/packages/server/src/api/routes/table.js +++ b/packages/server/src/api/routes/table.js @@ -9,7 +9,7 @@ const { } = require("@budibase/backend-core/permissions") const { tableValidator } = require("./utils/validators") -const router = Router() +const router = new Router() router /** diff --git a/packages/server/src/api/routes/templates.js b/packages/server/src/api/routes/templates.js index 710475db84..61a185b5c8 100644 --- a/packages/server/src/api/routes/templates.js +++ b/packages/server/src/api/routes/templates.js @@ -3,7 +3,7 @@ const controller = require("../controllers/templates") const authorized = require("../../middleware/authorized") const { BUILDER } = require("@budibase/backend-core/permissions") -const router = Router() +const router = new Router() router .get("/api/templates", authorized(BUILDER), controller.fetch) diff --git a/packages/server/src/api/routes/tests/row.spec.js b/packages/server/src/api/routes/tests/row.spec.js index 5cd282bb34..e85ffddee7 100644 --- a/packages/server/src/api/routes/tests/row.spec.js +++ b/packages/server/src/api/routes/tests/row.spec.js @@ -5,10 +5,12 @@ const { doInAppContext } = require("@budibase/backend-core/context") const { doInTenant } = require("@budibase/backend-core/tenancy") const { quotas, +} = require("@budibase/pro") +const { QuotaUsageType, StaticQuotaName, MonthlyQuotaName, -} = require("@budibase/pro") +} = require("@budibase/types") describe("/rows", () => { let request = setup.getRequest() diff --git a/packages/server/src/api/routes/user.js b/packages/server/src/api/routes/user.js index 5ac446d54e..a0eaf26ec6 100644 --- a/packages/server/src/api/routes/user.js +++ b/packages/server/src/api/routes/user.js @@ -6,7 +6,7 @@ const { PermissionTypes, } = require("@budibase/backend-core/permissions") -const router = Router() +const router = new Router() router .get( diff --git a/packages/server/src/api/routes/view.js b/packages/server/src/api/routes/view.js index 9d57d722e1..a7045f0814 100644 --- a/packages/server/src/api/routes/view.js +++ b/packages/server/src/api/routes/view.js @@ -9,7 +9,7 @@ const { PermissionLevels, } = require("@budibase/backend-core/permissions") -const router = Router() +const router = new Router() router .get("/api/views/export", authorized(BUILDER), viewController.exportView) diff --git a/packages/server/src/api/routes/webhook.js b/packages/server/src/api/routes/webhook.js index 9635638700..9d60438a63 100644 --- a/packages/server/src/api/routes/webhook.js +++ b/packages/server/src/api/routes/webhook.js @@ -4,7 +4,7 @@ const authorized = require("../../middleware/authorized") const { BUILDER } = require("@budibase/backend-core/permissions") const { webhookValidator } = require("./utils/validators") -const router = Router() +const router = new Router() router .get("/api/webhooks", authorized(BUILDER), controller.fetch) diff --git a/packages/server/src/automations/steps/sendSmtpEmail.js b/packages/server/src/automations/steps/sendSmtpEmail.js index 71e544a00d..423363701b 100644 --- a/packages/server/src/automations/steps/sendSmtpEmail.js +++ b/packages/server/src/automations/steps/sendSmtpEmail.js @@ -21,6 +21,14 @@ exports.definition = { type: "string", title: "Send From", }, + cc: { + type: "string", + title: "CC", + }, + bcc: { + type: "string", + title: "BCC", + }, subject: { type: "string", title: "Email Subject", @@ -49,13 +57,21 @@ exports.definition = { } exports.run = async function ({ inputs }) { - let { to, from, subject, contents } = inputs + let { to, from, subject, contents, cc, bcc } = inputs if (!contents) { contents = "

No content

" } to = to || undefined try { - let response = await sendSmtpEmail(to, from, subject, contents, true) + let response = await sendSmtpEmail( + to, + from, + subject, + contents, + cc, + bcc, + true + ) return { success: true, response, diff --git a/packages/server/src/db/index.js b/packages/server/src/db/index.js index 75ad19b87f..381c295d18 100644 --- a/packages/server/src/db/index.js +++ b/packages/server/src/db/index.js @@ -7,7 +7,7 @@ exports.init = () => { find: true, } - if (env.isTest()) { + if (env.isTest() && !env.COUCH_DB_URL) { dbConfig.inMemory = true dbConfig.allDbs = true } diff --git a/packages/server/src/definitions/openapi.ts b/packages/server/src/definitions/openapi.ts index a4bd0c1e3e..bb0ffb6771 100644 --- a/packages/server/src/definitions/openapi.ts +++ b/packages/server/src/definitions/openapi.ts @@ -5,491 +5,67 @@ export interface paths { "/applications": { - post: { - parameters: { - header: { - /** The ID of the app which this request is targeting. */ - "x-budibase-app-id": components["parameters"]["appId"]; - }; - }; - responses: { - /** Returns the created application. */ - 200: { - content: { - "application/json": components["schemas"]["applicationOutput"]; - }; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["application"]; - }; - }; - }; + post: operations["create"]; }; "/applications/{appId}": { - get: { - parameters: { - path: { - /** The ID of the app which this request is targeting. */ - appId: components["parameters"]["appIdUrl"]; - }; - }; - responses: { - /** Returns the retrieved application. */ - 200: { - content: { - "application/json": components["schemas"]["applicationOutput"]; - }; - }; - }; - }; - put: { - parameters: { - path: { - /** The ID of the app which this request is targeting. */ - appId: components["parameters"]["appIdUrl"]; - }; - }; - responses: { - /** Returns the updated application. */ - 200: { - content: { - "application/json": components["schemas"]["applicationOutput"]; - }; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["application"]; - }; - }; - }; - delete: { - parameters: { - path: { - /** The ID of the app which this request is targeting. */ - appId: components["parameters"]["appIdUrl"]; - }; - }; - responses: { - /** Returns the deleted application. */ - 200: { - content: { - "application/json": components["schemas"]["applicationOutput"]; - }; - }; - }; - }; + get: operations["getById"]; + put: operations["update"]; + delete: operations["destroy"]; }; "/applications/search": { /** Based on application properties (currently only name) search for applications. */ - post: { - responses: { - /** Returns the applications that were found based on the search parameters. */ - 200: { - content: { - "application/json": components["schemas"]["applicationSearch"]; - }; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["nameSearch"]; - }; - }; - }; + post: operations["search"]; }; "/queries/{queryId}": { /** Queries which have been created within a Budibase app can be executed using this, */ - post: { - parameters: { - path: { - /** The ID of the query which this request is targeting. */ - queryId: components["parameters"]["queryId"]; - }; - header: { - /** The ID of the app which this request is targeting. */ - "x-budibase-app-id": components["parameters"]["appId"]; - }; - }; - responses: { - /** Returns the result of the query execution. */ - 200: { - content: { - "application/json": components["schemas"]["executeQueryOutput"]; - }; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["executeQuery"]; - }; - }; - }; + post: operations["execute"]; }; "/queries/search": { /** Based on query properties (currently only name) search for queries. */ - post: { - parameters: { - header: { - /** The ID of the app which this request is targeting. */ - "x-budibase-app-id": components["parameters"]["appId"]; - }; - }; - responses: { - /** Returns the queries found based on the search parameters. */ - 200: { - content: { - "application/json": components["schemas"]["querySearch"]; - }; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["nameSearch"]; - }; - }; - }; + post: operations["search"]; }; "/tables/{tableId}/rows": { /** Creates a row within the specified table. */ - post: { - parameters: { - path: { - /** The ID of the table which this request is targeting. */ - tableId: components["parameters"]["tableId"]; - }; - header: { - /** The ID of the app which this request is targeting. */ - "x-budibase-app-id": components["parameters"]["appId"]; - }; - }; - responses: { - /** Returns the created row, including the ID which has been generated for it. This can be found in the Budibase portal, viewed under the developer information. */ - 200: { - content: { - "application/json": components["schemas"]["rowOutput"]; - }; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["row"]; - }; - }; - }; + post: operations["create"]; }; "/tables/{tableId}/rows/{rowId}": { /** This gets a single row, it will be enriched with the full related rows, rather than the squashed "primaryDisplay" format returned by the search endpoint. */ - get: { - parameters: { - path: { - /** The ID of the table which this request is targeting. */ - tableId: components["parameters"]["tableId"]; - /** The ID of the row which this request is targeting. */ - rowId: components["parameters"]["rowId"]; - }; - header: { - /** The ID of the app which this request is targeting. */ - "x-budibase-app-id": components["parameters"]["appId"]; - }; - }; - responses: { - /** Returns the retrieved row. */ - 200: { - content: { - "application/json": components["schemas"]["rowOutput"]; - }; - }; - }; - }; + get: operations["getById"]; /** Updates a row within the specified table. */ - put: { - parameters: { - path: { - /** The ID of the table which this request is targeting. */ - tableId: components["parameters"]["tableId"]; - /** The ID of the row which this request is targeting. */ - rowId: components["parameters"]["rowId"]; - }; - header: { - /** The ID of the app which this request is targeting. */ - "x-budibase-app-id": components["parameters"]["appId"]; - }; - }; - responses: { - /** Returns the created row, including the ID which has been generated for it. */ - 200: { - content: { - "application/json": components["schemas"]["rowOutput"]; - }; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["row"]; - }; - }; - }; + put: operations["update"]; /** Deletes a row within the specified table. */ - delete: { - parameters: { - path: { - /** The ID of the table which this request is targeting. */ - tableId: components["parameters"]["tableId"]; - /** The ID of the row which this request is targeting. */ - rowId: components["parameters"]["rowId"]; - }; - header: { - /** The ID of the app which this request is targeting. */ - "x-budibase-app-id": components["parameters"]["appId"]; - }; - }; - responses: { - /** Returns the deleted row, including the ID which has been generated for it. */ - 200: { - content: { - "application/json": components["schemas"]["rowOutput"]; - }; - }; - }; - }; + delete: operations["destroy"]; }; "/tables/{tableId}/rows/search": { - post: { - parameters: { - path: { - /** The ID of the table which this request is targeting. */ - tableId: components["parameters"]["tableId"]; - }; - header: { - /** The ID of the app which this request is targeting. */ - "x-budibase-app-id": components["parameters"]["appId"]; - }; - }; - responses: { - /** The response will contain an array of rows that match the search parameters. */ - 200: { - content: { - "application/json": components["schemas"]["searchOutput"]; - }; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["rowSearch"]; - }; - }; - }; + post: operations["search"]; }; "/tables": { /** Create a table, this could be internal or external. */ - post: { - parameters: { - header: { - /** The ID of the app which this request is targeting. */ - "x-budibase-app-id": components["parameters"]["appId"]; - }; - }; - responses: { - /** Returns the created table, including the ID which has been generated for it. This can be internal or external datasources. */ - 200: { - content: { - "application/json": components["schemas"]["tableOutput"]; - }; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["table"]; - }; - }; - }; + post: operations["create"]; }; "/tables/{tableId}": { /** Lookup a table, this could be internal or external. */ - get: { - parameters: { - path: { - /** The ID of the table which this request is targeting. */ - tableId: components["parameters"]["tableId"]; - }; - header: { - /** The ID of the app which this request is targeting. */ - "x-budibase-app-id": components["parameters"]["appId"]; - }; - }; - responses: { - /** Returns the retrieved table. */ - 200: { - content: { - "application/json": components["schemas"]["tableOutput"]; - }; - }; - }; - }; + get: operations["getById"]; /** Update a table, this could be internal or external. */ - put: { - parameters: { - path: { - /** The ID of the table which this request is targeting. */ - tableId: components["parameters"]["tableId"]; - }; - header: { - /** The ID of the app which this request is targeting. */ - "x-budibase-app-id": components["parameters"]["appId"]; - }; - }; - responses: { - /** Returns the updated table. */ - 200: { - content: { - "application/json": components["schemas"]["tableOutput"]; - }; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["table"]; - }; - }; - }; + put: operations["update"]; /** Delete a table, this could be internal or external. */ - delete: { - parameters: { - path: { - /** The ID of the table which this request is targeting. */ - tableId: components["parameters"]["tableId"]; - }; - header: { - /** The ID of the app which this request is targeting. */ - "x-budibase-app-id": components["parameters"]["appId"]; - }; - }; - responses: { - /** Returns the deleted table. */ - 200: { - content: { - "application/json": components["schemas"]["tableOutput"]; - }; - }; - }; - }; + delete: operations["destroy"]; }; "/tables/search": { /** Based on table properties (currently only name) search for tables. This could be an internal or an external table. */ - post: { - parameters: { - header: { - /** The ID of the app which this request is targeting. */ - "x-budibase-app-id": components["parameters"]["appId"]; - }; - }; - responses: { - /** Returns the found tables, based on the search parameters. */ - 200: { - content: { - "application/json": components["schemas"]["tableSearch"]; - }; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["nameSearch"]; - }; - }; - }; + post: operations["search"]; }; "/users": { - post: { - responses: { - /** Returns the created user. */ - 200: { - content: { - "application/json": components["schemas"]["userOutput"]; - }; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["user"]; - }; - }; - }; + post: operations["create"]; }; "/users/{userId}": { - get: { - parameters: { - path: { - /** The ID of the user which this request is targeting. */ - userId: components["parameters"]["userId"]; - }; - }; - responses: { - /** Returns the retrieved user. */ - 200: { - content: { - "application/json": components["schemas"]["userOutput"]; - }; - }; - }; - }; - put: { - parameters: { - path: { - /** The ID of the user which this request is targeting. */ - userId: components["parameters"]["userId"]; - }; - }; - responses: { - /** Returns the updated user. */ - 200: { - content: { - "application/json": components["schemas"]["userOutput"]; - }; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["user"]; - }; - }; - }; - delete: { - parameters: { - path: { - /** The ID of the user which this request is targeting. */ - userId: components["parameters"]["userId"]; - }; - }; - responses: { - /** Returns the deleted user. */ - 200: { - content: { - "application/json": components["schemas"]["userOutput"]; - }; - }; - }; - }; + get: operations["getById"]; + put: operations["update"]; + delete: operations["destroy"]; }; "/users/search": { /** Based on user properties (currently only name) search for users. */ - post: { - responses: { - /** Returns the found users based on search parameters. */ - 200: { - content: { - "application/json": components["schemas"]["userSearch"]; - }; - }; - }; - requestBody: { - content: { - "application/json": components["schemas"]["nameSearch"]; - }; - }; - }; + post: operations["search"]; }; } @@ -1127,6 +703,117 @@ export interface components { }; } -export interface operations {} +export interface operations { + create: { + responses: { + /** Returns the created user. */ + 200: { + content: { + "application/json": components["schemas"]["userOutput"]; + }; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["user"]; + }; + }; + }; + getById: { + parameters: { + path: { + /** The ID of the user which this request is targeting. */ + userId: components["parameters"]["userId"]; + }; + }; + responses: { + /** Returns the retrieved user. */ + 200: { + content: { + "application/json": components["schemas"]["userOutput"]; + }; + }; + }; + }; + update: { + parameters: { + path: { + /** The ID of the user which this request is targeting. */ + userId: components["parameters"]["userId"]; + }; + }; + responses: { + /** Returns the updated user. */ + 200: { + content: { + "application/json": components["schemas"]["userOutput"]; + }; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["user"]; + }; + }; + }; + destroy: { + parameters: { + path: { + /** The ID of the user which this request is targeting. */ + userId: components["parameters"]["userId"]; + }; + }; + responses: { + /** Returns the deleted user. */ + 200: { + content: { + "application/json": components["schemas"]["userOutput"]; + }; + }; + }; + }; + /** Based on user properties (currently only name) search for users. */ + search: { + responses: { + /** Returns the found users based on search parameters. */ + 200: { + content: { + "application/json": components["schemas"]["userSearch"]; + }; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["nameSearch"]; + }; + }; + }; + /** Queries which have been created within a Budibase app can be executed using this, */ + execute: { + parameters: { + path: { + /** The ID of the query which this request is targeting. */ + queryId: components["parameters"]["queryId"]; + }; + header: { + /** The ID of the app which this request is targeting. */ + "x-budibase-app-id": components["parameters"]["appId"]; + }; + }; + responses: { + /** Returns the result of the query execution. */ + 200: { + content: { + "application/json": components["schemas"]["executeQueryOutput"]; + }; + }; + }; + requestBody: { + content: { + "application/json": components["schemas"]["executeQuery"]; + }; + }; + }; +} export interface external {} diff --git a/packages/server/src/middleware/authorized.ts b/packages/server/src/middleware/authorized.ts index 298a50988a..1fa983a72a 100644 --- a/packages/server/src/middleware/authorized.ts +++ b/packages/server/src/middleware/authorized.ts @@ -52,9 +52,9 @@ const checkAuthorizedResource = async ( ) => { // get the user's roles const roleId = ctx.roleId || BUILTIN_ROLE_IDS.PUBLIC - const userRoles = await getUserRoleHierarchy(roleId, { + const userRoles = (await getUserRoleHierarchy(roleId, { idOnly: false, - }) + })) as { _id: string }[] const permError = "User does not have permission" // check if the user has the required role if (resourceRoles.length > 0) { diff --git a/packages/server/src/migrations/functions/usageQuotas/syncApps.ts b/packages/server/src/migrations/functions/usageQuotas/syncApps.ts index 24e4c21969..4770844a99 100644 --- a/packages/server/src/migrations/functions/usageQuotas/syncApps.ts +++ b/packages/server/src/migrations/functions/usageQuotas/syncApps.ts @@ -1,6 +1,7 @@ import { getTenantId } from "@budibase/backend-core/tenancy" import { getAllApps } from "@budibase/backend-core/db" -import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro" +import { quotas } from "@budibase/pro" +import { QuotaUsageType, StaticQuotaName } from "@budibase/types" export const run = async () => { // get app count diff --git a/packages/server/src/migrations/functions/usageQuotas/syncRows.ts b/packages/server/src/migrations/functions/usageQuotas/syncRows.ts index b92d880f7a..540ea6e819 100644 --- a/packages/server/src/migrations/functions/usageQuotas/syncRows.ts +++ b/packages/server/src/migrations/functions/usageQuotas/syncRows.ts @@ -1,7 +1,8 @@ import { getTenantId } from "@budibase/backend-core/tenancy" import { getAllApps } from "@budibase/backend-core/db" import { getUniqueRows } from "../../../utilities/usageQuota/rows" -import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro" +import { quotas } from "@budibase/pro" +import { QuotaUsageType, StaticQuotaName } from "@budibase/types" export const run = async () => { // get all rows in all apps diff --git a/packages/server/src/migrations/functions/usageQuotas/tests/syncApps.spec.ts b/packages/server/src/migrations/functions/usageQuotas/tests/syncApps.spec.ts index dbc978b9bd..d0d50395b2 100644 --- a/packages/server/src/migrations/functions/usageQuotas/tests/syncApps.spec.ts +++ b/packages/server/src/migrations/functions/usageQuotas/tests/syncApps.spec.ts @@ -1,6 +1,7 @@ import TestConfig from "../../../../tests/utilities/TestConfiguration" import * as syncApps from "../syncApps" -import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro" +import { quotas } from "@budibase/pro" +import { QuotaUsageType, StaticQuotaName } from "@budibase/types" describe("syncApps", () => { let config = new TestConfig(false) 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 851deb5417..b403179958 100644 --- a/packages/server/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts +++ b/packages/server/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts @@ -1,6 +1,7 @@ import TestConfig from "../../../../tests/utilities/TestConfiguration" import * as syncRows from "../syncRows" -import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro" +import { quotas } from "@budibase/pro" +import { QuotaUsageType, StaticQuotaName } from "@budibase/types" describe("syncRows", () => { let config = new TestConfig(false) diff --git a/packages/server/src/utilities/global.js b/packages/server/src/utilities/global.js index 462ef6ba5d..6d82f79ce2 100644 --- a/packages/server/src/utilities/global.js +++ b/packages/server/src/utilities/global.js @@ -43,9 +43,10 @@ exports.updateAppRole = (user, { appId } = {}) => { } async function checkGroupRoles(user, { appId } = {}) { - let roleId = await groups.getGroupRoleId(user, appId) - user.roleId = roleId - + if (user.roleId && user.roleId !== BUILTIN_ROLE_IDS.PUBLIC) { + return user + } + user.roleId = await groups.getGroupRoleId(user, appId) return user } @@ -74,8 +75,9 @@ exports.getRawGlobalUser = async userId => { } exports.getGlobalUser = async userId => { + const appId = getAppId() let user = await exports.getRawGlobalUser(userId) - return processUser(user) + return processUser(user, { appId }) } exports.getGlobalUsers = async (users = null) => { diff --git a/packages/server/src/utilities/users.js b/packages/server/src/utilities/users.js index e769441322..3fa222e677 100644 --- a/packages/server/src/utilities/users.js +++ b/packages/server/src/utilities/users.js @@ -2,10 +2,11 @@ const { InternalTables } = require("../db/utils") const { getGlobalUser } = require("../utilities/global") const { getAppDB } = require("@budibase/backend-core/context") const { getProdAppID } = require("@budibase/backend-core/db") +const { BUILTIN_ROLE_IDS } = require("@budibase/backend-core/roles") exports.getFullUser = async (ctx, userId) => { const global = await getGlobalUser(userId) - let metadata + let metadata = {} try { // this will throw an error if the db doesn't exist, or there is no appId const db = getAppDB() @@ -15,9 +16,11 @@ exports.getFullUser = async (ctx, userId) => { delete global._id delete global._rev } + delete metadata.csrfToken return { - ...global, ...metadata, + ...global, + roleId: global.roleId || BUILTIN_ROLE_IDS.PUBLIC, tableId: InternalTables.USER_METADATA, // make sure the ID is always a local ID, not a global one _id: userId, diff --git a/packages/server/src/utilities/workerRequests.js b/packages/server/src/utilities/workerRequests.js index e08ad147d1..53f13b6e02 100644 --- a/packages/server/src/utilities/workerRequests.js +++ b/packages/server/src/utilities/workerRequests.js @@ -54,7 +54,15 @@ async function checkResponse(response, errorMsg, { ctx } = {}) { exports.request = request // have to pass in the tenant ID as this could be coming from an automation -exports.sendSmtpEmail = async (to, from, subject, contents, automation) => { +exports.sendSmtpEmail = async ( + to, + from, + subject, + contents, + cc, + bcc, + automation +) => { // tenant ID will be set in header const response = await fetch( checkSlashesInUrl(env.WORKER_URL + `/api/global/email/send`), @@ -65,6 +73,8 @@ exports.sendSmtpEmail = async (to, from, subject, contents, automation) => { from, contents, subject, + cc, + bcc, purpose: "custom", automation, }, diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock index ff0be9e9e0..04d54f3c46 100644 --- a/packages/server/yarn.lock +++ b/packages/server/yarn.lock @@ -1094,12 +1094,12 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@1.4.17": - version "1.4.17" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.4.17.tgz#680e2de7cc4cb598c29438cc00207cb0f8750555" - integrity sha512-e4ahZnPnRXTFohD17pkDO1uxP44elbH2RFpvHodQ+jzOQPwi3NWAKi7+3BbagRzoLv7Q9Mq8IhIBZrYLntKS6g== +"@budibase/backend-core@1.4.18-alpha.0": + version "1.4.18-alpha.0" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.4.18-alpha.0.tgz#27c77d0c28a17a2ee67ad0ada1431f4f03e34747" + integrity sha512-eP7v7MaULTi8ieWo0qHuXH8E2wv+8C+2FOdc4ah/af+MFP2lslfhlwF5X6aSkzODV9KbaQr1by0ytM7QS+nH6A== dependencies: - "@budibase/types" "^1.4.17" + "@budibase/types" "1.4.18-alpha.0" "@shopify/jest-koa-mocks" "5.0.1" "@techpass/passport-openidconnect" "0.3.2" aws-sdk "2.1030.0" @@ -1180,13 +1180,13 @@ svelte-flatpickr "^3.2.3" svelte-portal "^1.0.0" -"@budibase/pro@1.4.17": - version "1.4.17" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.4.17.tgz#0648965741e77597a216806aa7e1b71212c87cc1" - integrity sha512-2ug6e8dKntOW9Fmxnr++76eV/n7CXlEfUnbVyQM8vixofCPTFBQ1mL6nAg1Cc4dx6x8grhb2o5OIydhgv0bVSQ== +"@budibase/pro@1.4.18-alpha.0": + version "1.4.18-alpha.0" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.4.18-alpha.0.tgz#e9910569a769e5ce107f8200ccba5295dc365fa0" + integrity sha512-GsWDZb1H3Cm3vhY8n5+eekS14pjJRI7SRDt838ff4ECLpTp6YSVnOkIwms8g7uQUuXa8HbSBDl50W93wTR4QdQ== dependencies: - "@budibase/backend-core" "1.4.17" - "@budibase/types" "1.4.17" + "@budibase/backend-core" "1.4.18-alpha.0" + "@budibase/types" "1.4.18-alpha.0" "@koa/router" "8.0.8" joi "17.6.0" node-fetch "^2.6.1" @@ -1209,10 +1209,10 @@ svelte-apexcharts "^1.0.2" svelte-flatpickr "^3.1.0" -"@budibase/types@1.4.17", "@budibase/types@^1.4.17": - version "1.4.17" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-1.4.17.tgz#ca71fcfe202856d15fe25110edf76d81978a7dd1" - integrity sha512-JDJVx/OkvfZmH2z4rqc7qx/XyDiL/DfgGS5U+pHqQXdxO+OapfoT/Lj/X3afnvlzN/lg2h8IERLU2Ns81D2DIw== +"@budibase/types@1.4.18-alpha.0": + version "1.4.18-alpha.0" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-1.4.18-alpha.0.tgz#f1abbef32395659ba53176fdd485557fb0f66487" + integrity sha512-UIjVotIUzu4v9IVzqEzwQdusyr5bxfET89bZ2+mTeUIj5xzWmS6z4vlBlDv2nfZThFKvXDXE5YFgzSGdESBIrA== "@bull-board/api@3.7.0": version "3.7.0" diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index 4bc3b14998..21c5c318df 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "1.4.17", + "version": "1.4.18-alpha.0", "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 f88101656b..e7ee0ba32a 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/types", - "version": "1.4.17", + "version": "1.4.18-alpha.0", "description": "Budibase types", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/types/src/api/web/user.ts b/packages/types/src/api/web/user.ts index b2c17575c2..c66d3203e8 100644 --- a/packages/types/src/api/web/user.ts +++ b/packages/types/src/api/web/user.ts @@ -6,28 +6,31 @@ export interface CreateUserResponse { email: string } -export interface BulkCreateUsersRequest { - users: User[] - groups: any[] -} - export interface UserDetails { _id: string email: string } -export interface BulkCreateUsersResponse { - successful: UserDetails[] - unsuccessful: { email: string; reason: string }[] +export interface BulkUserRequest { + delete?: { + userIds: string[] + } + create?: { + users: User[] + groups: any[] + } } -export interface BulkDeleteUsersRequest { - userIds: string[] -} - -export interface BulkDeleteUsersResponse { - successful: UserDetails[] - unsuccessful: { _id: string; email: string; reason: string }[] +export interface BulkUserResponse { + created?: { + successful: UserDetails[] + unsuccessful: { email: string; reason: string }[] + } + deleted?: { + successful: UserDetails[] + unsuccessful: { _id: string; email: string; reason: string }[] + } + message?: string } export interface InviteUserRequest { diff --git a/packages/types/src/documents/account/account.ts b/packages/types/src/documents/account/account.ts index 33c96033a0..e7dcf2d89f 100644 --- a/packages/types/src/documents/account/account.ts +++ b/packages/types/src/documents/account/account.ts @@ -1,4 +1,4 @@ -import { Hosting } from "../../sdk" +import { Feature, Hosting, PlanType, Quotas } from "../../sdk" export interface CreateAccount { email: string @@ -22,6 +22,11 @@ export const isCreatePasswordAccount = ( account: CreateAccount ): account is CreatePassswordAccount => account.authType === AuthType.PASSWORD +export interface LicenseOverrides { + features?: Feature[] + quotas?: Quotas +} + export interface Account extends CreateAccount { // generated accountId: string @@ -31,9 +36,12 @@ export interface Account extends CreateAccount { verificationSent: boolean // licensing tier: string // deprecated + planType?: PlanType + planTier?: number stripeCustomerId?: string licenseKey?: string licenseKeyActivatedAt?: number + licenseOverrides?: LicenseOverrides } export interface PasswordAccount extends Account { diff --git a/packages/types/src/documents/global/index.ts b/packages/types/src/documents/global/index.ts index 1f8bb4a84f..84684df369 100644 --- a/packages/types/src/documents/global/index.ts +++ b/packages/types/src/documents/global/index.ts @@ -2,3 +2,4 @@ export * from "./config" export * from "./user" export * from "./userGroup" export * from "./plugin" +export * from "./quotas" diff --git a/packages/types/src/documents/global/quotas.ts b/packages/types/src/documents/global/quotas.ts new file mode 100644 index 0000000000..b90c7e0ddb --- /dev/null +++ b/packages/types/src/documents/global/quotas.ts @@ -0,0 +1,15 @@ +import { MonthlyQuotaName, StaticQuotaName } from "../../sdk" + +export interface QuotaUsage { + _id: string + _rev?: string + quotaReset: string + usageQuota: { + [key in StaticQuotaName]: number + } + monthly: { + [key: string]: { + [key in MonthlyQuotaName]: number + } + } +} diff --git a/packages/types/src/documents/global/userGroup.ts b/packages/types/src/documents/global/userGroup.ts index 86010d118b..cda74b0536 100644 --- a/packages/types/src/documents/global/userGroup.ts +++ b/packages/types/src/documents/global/userGroup.ts @@ -4,9 +4,8 @@ export interface UserGroup extends Document { name: string icon: string color: string - users: GroupUser[] - apps: string[] - roles: UserGroupRoles + users?: GroupUser[] + roles?: UserGroupRoles createdAt?: number } diff --git a/packages/types/src/sdk/events/event.ts b/packages/types/src/sdk/events/event.ts index de56740e44..73e5315713 100644 --- a/packages/types/src/sdk/events/event.ts +++ b/packages/types/src/sdk/events/event.ts @@ -133,9 +133,14 @@ export enum Event { AUTOMATION_TRIGGER_UPDATED = "automation:trigger:updated", // LICENSE - LICENSE_UPGRADED = "license:upgraded", - LICENSE_DOWNGRADED = "license:downgraded", + LICENSE_PLAN_CHANGED = "license:plan:changed", + LICENSE_TIER_CHANGED = "license:tier:changed", LICENSE_ACTIVATED = "license:activated", + LICENSE_PAYMENT_FAILED = "license:payment:failed", + LICENSE_PAYMENT_RECOVERED = "license:payment:recovered", + LICENSE_CHECKOUT_OPENED = "license:checkout:opened", + LICENSE_CHECKOUT_SUCCESS = "license:checkout:success", + LICENSE_PORTAL_OPENED = "license:portal:opened", // ACCOUNT ACCOUNT_CREATED = "account:created", diff --git a/packages/types/src/sdk/events/license.ts b/packages/types/src/sdk/events/license.ts index 771327c960..a12fc6bbb5 100644 --- a/packages/types/src/sdk/events/license.ts +++ b/packages/types/src/sdk/events/license.ts @@ -1,7 +1,37 @@ -export interface LicenseUpgradedEvent {} +import { PlanType } from "../licensing" -export interface LicenseDowngradedEvent {} +export interface LicenseTierChangedEvent { + accountId: string + from: number + to: number +} -export interface LicenseUpdatedEvent {} +export interface LicensePlanChangedEvent { + accountId: string + from: PlanType + to: PlanType +} -export interface LicenseActivatedEvent {} +export interface LicenseActivatedEvent { + accountId: string +} + +export interface LicenseCheckoutOpenedEvent { + accountId: string +} + +export interface LicenseCheckoutSuccessEvent { + accountId: string +} + +export interface LicensePortalOpenedEvent { + accountId: string +} + +export interface LicensePaymentFailedEvent { + accountId: string +} + +export interface LicensePaymentRecoveredEvent { + accountId: string +} diff --git a/packages/types/src/sdk/licensing/billing.ts b/packages/types/src/sdk/licensing/billing.ts index da2aca1615..d4365525db 100644 --- a/packages/types/src/sdk/licensing/billing.ts +++ b/packages/types/src/sdk/licensing/billing.ts @@ -12,6 +12,9 @@ export interface Subscription { cancelAt: number | null | undefined currentPeriodStart: number currentPeriodEnd: number + status: string + pastDueAt?: number | null + downgradeAt?: number } export interface Billing { diff --git a/packages/types/src/sdk/licensing/plan.ts b/packages/types/src/sdk/licensing/plan.ts index 6b226887b4..b370397534 100644 --- a/packages/types/src/sdk/licensing/plan.ts +++ b/packages/types/src/sdk/licensing/plan.ts @@ -6,6 +6,7 @@ export interface AccountPlan { export enum PlanType { FREE = "free", PRO = "pro", + TEAM = "team", BUSINESS = "business", ENTERPRISE = "enterprise", } diff --git a/packages/types/src/sdk/licensing/quota.ts b/packages/types/src/sdk/licensing/quota.ts index 578a5d98d0..2f9a8f918c 100644 --- a/packages/types/src/sdk/licensing/quota.ts +++ b/packages/types/src/sdk/licensing/quota.ts @@ -13,6 +13,8 @@ export enum QuotaType { export enum StaticQuotaName { ROWS = "rows", APPS = "apps", + USER_GROUPS = "userGroups", + PLUGINS = "plugins", } export enum MonthlyQuotaName { @@ -22,7 +24,6 @@ export enum MonthlyQuotaName { } export enum ConstantQuotaName { - QUERY_TIMEOUT_SECONDS = "queryTimeoutSeconds", AUTOMATION_LOG_RETENTION_DAYS = "automationLogRetentionDays", } @@ -54,6 +55,7 @@ export const isConstantQuota = ( export type PlanQuotas = { [PlanType.FREE]: Quotas [PlanType.PRO]: Quotas + [PlanType.TEAM]: Quotas [PlanType.BUSINESS]: Quotas [PlanType.ENTERPRISE]: Quotas } @@ -68,10 +70,11 @@ export type Quotas = { [QuotaUsageType.STATIC]: { [StaticQuotaName.ROWS]: Quota [StaticQuotaName.APPS]: Quota + [StaticQuotaName.USER_GROUPS]: Quota + [StaticQuotaName.PLUGINS]: Quota } } [QuotaType.CONSTANT]: { - [ConstantQuotaName.QUERY_TIMEOUT_SECONDS]: Quota [ConstantQuotaName.AUTOMATION_LOG_RETENTION_DAYS]: Quota } } diff --git a/packages/worker/Dockerfile b/packages/worker/Dockerfile index 883a6c299b..046b844815 100644 --- a/packages/worker/Dockerfile +++ b/packages/worker/Dockerfile @@ -23,5 +23,7 @@ ENV NODE_ENV=production ENV CLUSTER_MODE=${CLUSTER_MODE} ENV SERVICE=worker-service ENV POSTHOG_TOKEN=phc_bIjZL7oh2GEUd2vqvTBH8WvrX0fWTFQMs6H5KQxiUxU +ENV TENANT_FEATURE_FLAGS=*:LICENSING,*:USER_GROUPS +ENV ACCOUNT_PORTAL_URL=https://account.budibase.app CMD ["./docker_run.sh"] diff --git a/packages/worker/package.json b/packages/worker/package.json index c0618d699c..132570545d 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/worker", "email": "hi@budibase.com", - "version": "1.4.17", + "version": "1.4.18-alpha.0", "description": "Budibase background service", "main": "src/index.ts", "repository": { @@ -36,10 +36,10 @@ "author": "Budibase", "license": "GPL-3.0", "dependencies": { - "@budibase/backend-core": "^1.4.17", - "@budibase/pro": "1.4.17", - "@budibase/string-templates": "^1.4.17", - "@budibase/types": "^1.4.17", + "@budibase/backend-core": "1.4.18-alpha.0", + "@budibase/pro": "1.4.18-alpha.0", + "@budibase/string-templates": "1.4.18-alpha.0", + "@budibase/types": "1.4.18-alpha.0", "@koa/router": "8.0.8", "@sentry/node": "6.17.7", "@techpass/passport-openidconnect": "0.3.2", diff --git a/packages/worker/scripts/dev/manage.js b/packages/worker/scripts/dev/manage.js index 96f5c29af4..a4eaf37162 100644 --- a/packages/worker/scripts/dev/manage.js +++ b/packages/worker/scripts/dev/manage.js @@ -28,6 +28,7 @@ async function init() { APPS_URL: "http://localhost:4001", SERVICE: "worker-service", DEPLOYMENT_ENVIRONMENT: "development", + TENANT_FEATURE_FLAGS: "*:LICENSING,*:USER_GROUPS", } let envFile = "" Object.keys(envFileJson).forEach(key => { diff --git a/packages/worker/src/api/controllers/global/auth.ts b/packages/worker/src/api/controllers/global/auth.ts index 834531cd78..c27fe17ee7 100644 --- a/packages/worker/src/api/controllers/global/auth.ts +++ b/packages/worker/src/api/controllers/global/auth.ts @@ -8,7 +8,7 @@ const { checkResetPasswordCode } = require("../../../utilities/redis") const { getGlobalDB } = require("@budibase/backend-core/tenancy") const env = require("../../../environment") import { events, users as usersCore, context } from "@budibase/backend-core" -import { users } from "../../../sdk" +import sdk from "../../../sdk" import { User } from "@budibase/types" export const googleCallbackUrl = async (config: any) => { @@ -167,7 +167,11 @@ export const googlePreAuth = async (ctx: any, next: any) => { workspace: ctx.query.workspace, }) let callbackUrl = await exports.googleCallbackUrl(config) - const strategy = await google.strategyFactory(config, callbackUrl, users.save) + const strategy = await google.strategyFactory( + config, + callbackUrl, + sdk.users.save + ) return passport.authenticate(strategy, { scope: ["profile", "email"], @@ -184,7 +188,11 @@ export const googleAuth = async (ctx: any, next: any) => { workspace: ctx.query.workspace, }) const callbackUrl = await exports.googleCallbackUrl(config) - const strategy = await google.strategyFactory(config, callbackUrl, users.save) + const strategy = await google.strategyFactory( + config, + callbackUrl, + sdk.users.save + ) return passport.authenticate( strategy, @@ -214,7 +222,7 @@ export const oidcStrategyFactory = async (ctx: any, configId: any) => { chosenConfig, callbackUrl ) - return oidc.strategyFactory(enrichedConfig, users.save) + return oidc.strategyFactory(enrichedConfig, sdk.users.save) } /** diff --git a/packages/worker/src/api/controllers/global/email.js b/packages/worker/src/api/controllers/global/email.js index 125376cdc2..85e39be0da 100644 --- a/packages/worker/src/api/controllers/global/email.js +++ b/packages/worker/src/api/controllers/global/email.js @@ -10,6 +10,8 @@ exports.sendEmail = async ctx => { contents, from, subject, + cc, + bcc, automation, } = ctx.request.body let user @@ -23,6 +25,8 @@ exports.sendEmail = async ctx => { contents, from, subject, + cc, + bcc, automation, }) ctx.body = { diff --git a/packages/worker/src/api/controllers/global/license.ts b/packages/worker/src/api/controllers/global/license.ts index 1e5ca9beac..2bd173010f 100644 --- a/packages/worker/src/api/controllers/global/license.ts +++ b/packages/worker/src/api/controllers/global/license.ts @@ -24,6 +24,11 @@ export const getInfo = async (ctx: any) => { ctx.status = 200 } +export const deleteInfo = async (ctx: any) => { + await licensing.deleteLicenseInfo() + ctx.status = 200 +} + export const getQuotaUsage = async (ctx: any) => { ctx.body = await quotas.getQuotaUsage() } diff --git a/packages/worker/src/api/controllers/global/self.js b/packages/worker/src/api/controllers/global/self.ts similarity index 65% rename from packages/worker/src/api/controllers/global/self.js rename to packages/worker/src/api/controllers/global/self.ts index 4d71e636c9..685e2c8243 100644 --- a/packages/worker/src/api/controllers/global/self.js +++ b/packages/worker/src/api/controllers/global/self.ts @@ -1,39 +1,37 @@ -const { - getGlobalDB, - getTenantId, - isUserInAppTenant, -} = require("@budibase/backend-core/tenancy") -const { generateDevInfoID, SEPARATOR } = require("@budibase/backend-core/db") -const { user: userCache } = require("@budibase/backend-core/cache") -const { - hash, - platformLogout, - getCookie, - clearCookie, -} = require("@budibase/backend-core/utils") -const { encrypt } = require("@budibase/backend-core/encryption") -const { newid } = require("@budibase/backend-core/utils") -const { users } = require("../../../sdk") -const { Cookies } = require("@budibase/backend-core/constants") -const { events, featureFlags } = require("@budibase/backend-core") -const env = require("../../../environment") +import sdk from "../../../sdk" +import { + events, + featureFlags, + tenancy, + constants, + db as dbCore, + utils, + cache, + encryption, +} from "@budibase/backend-core" +import env from "../../../environment" +import { groups } from "@budibase/pro" +const { hash, platformLogout, getCookie, clearCookie, newid } = utils +const { user: userCache } = cache function newTestApiKey() { return env.ENCRYPTED_TEST_PUBLIC_API_KEY } function newApiKey() { - return encrypt(`${getTenantId()}${SEPARATOR}${newid()}`) + return encryption.encrypt( + `${tenancy.getTenantId()}${dbCore.SEPARATOR}${newid()}` + ) } -function cleanupDevInfo(info) { +function cleanupDevInfo(info: any) { // user doesn't need to aware of dev doc info delete info._id delete info._rev return info } -exports.generateAPIKey = async ctx => { +export async function generateAPIKey(ctx: any) { let userId let apiKey if (env.isTest() && ctx.request.body.userId) { @@ -44,8 +42,8 @@ exports.generateAPIKey = async ctx => { apiKey = newApiKey() } - const db = getGlobalDB() - const id = generateDevInfoID(userId) + const db = tenancy.getGlobalDB() + const id = dbCore.generateDevInfoID(userId) let devInfo try { devInfo = await db.get(id) @@ -57,9 +55,9 @@ exports.generateAPIKey = async ctx => { ctx.body = cleanupDevInfo(devInfo) } -exports.fetchAPIKey = async ctx => { - const db = getGlobalDB() - const id = generateDevInfoID(ctx.user._id) +export async function fetchAPIKey(ctx: any) { + const db = tenancy.getGlobalDB() + const id = dbCore.generateDevInfoID(ctx.user._id) let devInfo try { devInfo = await db.get(id) @@ -74,20 +72,20 @@ exports.fetchAPIKey = async ctx => { ctx.body = cleanupDevInfo(devInfo) } -const checkCurrentApp = ctx => { - const appCookie = getCookie(ctx, Cookies.CurrentApp) - if (appCookie && !isUserInAppTenant(appCookie.appId)) { +const checkCurrentApp = (ctx: any) => { + const appCookie = getCookie(ctx, constants.Cookies.CurrentApp) + if (appCookie && !tenancy.isUserInAppTenant(appCookie.appId)) { // there is a currentapp cookie from another tenant // remove the cookie as this is incompatible with the builder // due to builder and admin permissions being removed - clearCookie(ctx, Cookies.CurrentApp) + clearCookie(ctx, constants.Cookies.CurrentApp) } } /** * Add the attributes that are session based to the current user. */ -const addSessionAttributesToUser = ctx => { +const addSessionAttributesToUser = (ctx: any) => { ctx.body.account = ctx.user.account ctx.body.license = ctx.user.license ctx.body.budibaseAccess = !!ctx.user.budibaseAccess @@ -95,9 +93,9 @@ const addSessionAttributesToUser = ctx => { ctx.body.csrfToken = ctx.user.csrfToken } -const sanitiseUserUpdate = ctx => { +const sanitiseUserUpdate = (ctx: any) => { const allowed = ["firstName", "lastName", "password", "forceResetPassword"] - const resp = {} + const resp: { [key: string]: any } = {} for (let [key, value] of Object.entries(ctx.request.body)) { if (allowed.includes(key)) { resp[key] = value @@ -106,7 +104,7 @@ const sanitiseUserUpdate = ctx => { return resp } -exports.getSelf = async ctx => { +export async function getSelf(ctx: any) { if (!ctx.user) { ctx.throw(403, "User not logged in") } @@ -118,17 +116,18 @@ exports.getSelf = async ctx => { checkCurrentApp(ctx) // get the main body of the user - ctx.body = await users.getUser(userId) + const user = await sdk.users.getUser(userId) + ctx.body = await groups.enrichUserRolesFromGroups(user) // add the feature flags for this tenant - const tenantId = getTenantId() + const tenantId = tenancy.getTenantId() ctx.body.featureFlags = featureFlags.getTenantFeatureFlags(tenantId) addSessionAttributesToUser(ctx) } -exports.updateSelf = async ctx => { - const db = getGlobalDB() +export async function updateSelf(ctx: any) { + const db = tenancy.getGlobalDB() const user = await db.get(ctx.user._id) let passwordChange = false diff --git a/packages/worker/src/api/controllers/global/templates.js b/packages/worker/src/api/controllers/global/templates.ts similarity index 59% rename from packages/worker/src/api/controllers/global/templates.js rename to packages/worker/src/api/controllers/global/templates.ts index b16e9423ec..0abce704c7 100644 --- a/packages/worker/src/api/controllers/global/templates.js +++ b/packages/worker/src/api/controllers/global/templates.ts @@ -1,20 +1,19 @@ -const { generateTemplateID } = require("@budibase/backend-core/db") -const { +import { TemplateMetadata, TemplateBindings, GLOBAL_OWNER, -} = require("../../../constants") -const { getTemplates } = require("../../../constants/templates") -const { getGlobalDB } = require("@budibase/backend-core/tenancy") +} from "../../../constants" +import { getTemplates } from "../../../constants/templates" +import { tenancy, db as dbCore } from "@budibase/backend-core" -exports.save = async ctx => { - const db = getGlobalDB() +export async function save(ctx: any) { + const db = tenancy.getGlobalDB() let template = ctx.request.body if (!template.ownerId) { template.ownerId = GLOBAL_OWNER } if (!template._id) { - template._id = generateTemplateID(template.ownerId) + template._id = dbCore.generateTemplateID(template.ownerId) } const response = await db.put(template) @@ -24,9 +23,9 @@ exports.save = async ctx => { } } -exports.definitions = async ctx => { - const bindings = {} - const info = {} +export async function definitions(ctx: any) { + const bindings: any = {} + const info: any = {} for (let template of TemplateMetadata.email) { bindings[template.purpose] = template.bindings info[template.purpose] = { @@ -45,30 +44,33 @@ exports.definitions = async ctx => { } } -exports.fetch = async ctx => { +export async function fetch(ctx: any) { ctx.body = await getTemplates() } -exports.fetchByType = async ctx => { +export async function fetchByType(ctx: any) { + // @ts-ignore ctx.body = await getTemplates({ type: ctx.params.type, }) } -exports.fetchByOwner = async ctx => { +export async function fetchByOwner(ctx: any) { + // @ts-ignore ctx.body = await getTemplates({ ownerId: ctx.params.ownerId, }) } -exports.find = async ctx => { +export async function find(ctx: any) { + // @ts-ignore ctx.body = await getTemplates({ id: ctx.params.id, }) } -exports.destroy = async ctx => { - const db = getGlobalDB() +export async function destroy(ctx: any) { + const db = tenancy.getGlobalDB() await db.remove(ctx.params.id, ctx.params.rev) ctx.message = `Template ${ctx.params.id} deleted.` ctx.status = 200 diff --git a/packages/worker/src/api/controllers/global/users.ts b/packages/worker/src/api/controllers/global/users.ts index ea9375f238..8894330f67 100644 --- a/packages/worker/src/api/controllers/global/users.ts +++ b/packages/worker/src/api/controllers/global/users.ts @@ -1,8 +1,9 @@ import { checkInviteCode } from "../../../utilities/redis" -import { users } from "../../../sdk" +import sdk from "../../../sdk" import env from "../../../environment" import { - BulkDeleteUsersRequest, + BulkUserRequest, + BulkUserResponse, CloudAccount, InviteUserRequest, InviteUsersRequest, @@ -16,46 +17,48 @@ import { tenancy, } from "@budibase/backend-core" import { checkAnyUserExists } from "../../../utilities/users" -import { groups as groupUtils } from "@budibase/pro" const MAX_USERS_UPLOAD_LIMIT = 1000 export const save = async (ctx: any) => { try { - ctx.body = await users.save(ctx.request.body) + ctx.body = await sdk.users.save(ctx.request.body) } catch (err: any) { ctx.throw(err.status || 400, err) } } -export const bulkCreate = async (ctx: any) => { - let { users: newUsersRequested, groups } = ctx.request.body +const bulkDelete = async (userIds: string[], currentUserId: string) => { + if (userIds?.indexOf(currentUserId) !== -1) { + throw new Error("Unable to delete self.") + } + return await sdk.users.bulkDelete(userIds) +} - if (!env.SELF_HOSTED && newUsersRequested.length > MAX_USERS_UPLOAD_LIMIT) { - ctx.throw( - 400, +const bulkCreate = async (users: User[], groupIds: string[]) => { + if (!env.SELF_HOSTED && users.length > MAX_USERS_UPLOAD_LIMIT) { + throw new Error( "Max limit for upload is 1000 users. Please reduce file size and try again." ) } + return await sdk.users.bulkCreate(users, groupIds) +} - const db = tenancy.getGlobalDB() - let groupsToSave: any[] = [] - - if (groups.length) { - for (const groupId of groups) { - let oldGroup = await db.get(groupId) - groupsToSave.push(oldGroup) - } - } - +export const bulkUpdate = async (ctx: any) => { + const currentUserId = ctx.user._id + const input = ctx.request.body as BulkUserRequest + let created, deleted try { - const response = await users.bulkCreate(newUsersRequested, groups) - await groupUtils.bulkSaveGroupUsers(groupsToSave, response.successful) - - ctx.body = response + if (input.create) { + created = await bulkCreate(input.create.users, input.create.groups) + } + if (input.delete) { + deleted = await bulkDelete(input.delete.userIds, currentUserId) + } } catch (err: any) { - ctx.throw(err.status || 400, err) + ctx.throw(err.status || 400, err?.message || err) } + ctx.body = { created, deleted } as BulkUserResponse } const parseBooleanParam = (param: any) => { @@ -99,7 +102,7 @@ export const adminUser = async (ctx: any) => { // always bust checklist beforehand, if an error occurs but can proceed, don't get // stuck in a cycle await cache.bustCache(cache.CacheKeys.CHECKLIST) - const finalUser = await users.save(user, { + const finalUser = await sdk.users.save(user, { hashPassword, requirePassword, }) @@ -121,7 +124,7 @@ export const adminUser = async (ctx: any) => { export const countByApp = async (ctx: any) => { const appId = ctx.params.appId try { - ctx.body = await users.countUsersByApp(appId) + ctx.body = await sdk.users.countUsersByApp(appId) } catch (err: any) { ctx.throw(err.status || 400, err) } @@ -133,28 +136,15 @@ export const destroy = async (ctx: any) => { ctx.throw(400, "Unable to delete self.") } - await users.destroy(id, ctx.user) + await sdk.users.destroy(id, ctx.user) ctx.body = { message: `User ${id} deleted.`, } } -export const bulkDelete = async (ctx: any) => { - const { userIds } = ctx.request.body as BulkDeleteUsersRequest - if (userIds?.indexOf(ctx.user._id) !== -1) { - ctx.throw(400, "Unable to delete self.") - } - - try { - ctx.body = await users.bulkDelete(userIds) - } catch (err) { - ctx.throw(err) - } -} - export const search = async (ctx: any) => { - const paginated = await users.paginatedUsers(ctx.request.body) + const paginated = await sdk.users.paginatedUsers(ctx.request.body) // user hashed password shouldn't ever be returned for (let user of paginated.data) { if (user) { @@ -166,7 +156,7 @@ export const search = async (ctx: any) => { // called internally by app server user fetch export const fetch = async (ctx: any) => { - const all = await users.allUsers() + const all = await sdk.users.allUsers() // user hashed password shouldn't ever be returned for (let user of all) { if (user) { @@ -178,7 +168,7 @@ export const fetch = async (ctx: any) => { // called internally by app server user find export const find = async (ctx: any) => { - ctx.body = await users.getUser(ctx.params.id) + ctx.body = await sdk.users.getUser(ctx.params.id) } export const tenantUserLookup = async (ctx: any) => { @@ -193,7 +183,7 @@ export const tenantUserLookup = async (ctx: any) => { export const invite = async (ctx: any) => { const request = ctx.request.body as InviteUserRequest - const response = await users.invite([request]) + const response = await sdk.users.invite([request]) // explicitly throw for single user invite if (response.unsuccessful.length) { @@ -212,7 +202,7 @@ export const invite = async (ctx: any) => { export const inviteMultiple = async (ctx: any) => { const request = ctx.request.body as InviteUsersRequest - ctx.body = await users.invite(request) + ctx.body = await sdk.users.invite(request) } export const inviteAccept = async (ctx: any) => { @@ -221,7 +211,7 @@ export const inviteAccept = async (ctx: any) => { // info is an extension of the user object that was stored by global const { email, info }: any = await checkInviteCode(inviteCode) ctx.body = await tenancy.doInTenant(info.tenantId, async () => { - const saved = await users.save({ + const saved = await sdk.users.save({ firstName, lastName, password, diff --git a/packages/worker/src/api/controllers/system/accounts.ts b/packages/worker/src/api/controllers/system/accounts.ts index 5e72f35bab..0aa5f25785 100644 --- a/packages/worker/src/api/controllers/system/accounts.ts +++ b/packages/worker/src/api/controllers/system/accounts.ts @@ -1,21 +1,21 @@ import { Account, AccountMetadata } from "@budibase/types" -import { accounts } from "../../../sdk" +import sdk from "../../../sdk" export const save = async (ctx: any) => { const account = ctx.request.body as Account let metadata: AccountMetadata = { - _id: accounts.formatAccountMetadataId(account.accountId), + _id: sdk.accounts.formatAccountMetadataId(account.accountId), email: account.email, } - metadata = await accounts.saveMetadata(metadata) + metadata = await sdk.accounts.saveMetadata(metadata) ctx.body = metadata ctx.status = 200 } export const destroy = async (ctx: any) => { - const accountId = accounts.formatAccountMetadataId(ctx.params.accountId) - await accounts.destroyMetadata(accountId) + const accountId = sdk.accounts.formatAccountMetadataId(ctx.params.accountId) + await sdk.accounts.destroyMetadata(accountId) ctx.status = 204 } diff --git a/packages/worker/src/api/routes/global/auth.js b/packages/worker/src/api/routes/global/auth.js index 07d95f808d..1c292cdc7f 100644 --- a/packages/worker/src/api/routes/global/auth.js +++ b/packages/worker/src/api/routes/global/auth.js @@ -4,7 +4,7 @@ const { joiValidator } = require("@budibase/backend-core/auth") const Joi = require("joi") const { updateTenantId } = require("@budibase/backend-core/tenancy") -const router = Router() +const router = new Router() function buildAuthValidation() { // prettier-ignore diff --git a/packages/worker/src/api/routes/global/configs.js b/packages/worker/src/api/routes/global/configs.js index e08611b73a..a7cd1a38e8 100644 --- a/packages/worker/src/api/routes/global/configs.js +++ b/packages/worker/src/api/routes/global/configs.js @@ -5,7 +5,7 @@ const { adminOnly } = require("@budibase/backend-core/auth") const Joi = require("joi") const { Configs } = require("../../../constants") -const router = Router() +const router = new Router() function smtpValidation() { // prettier-ignore diff --git a/packages/worker/src/api/routes/global/email.js b/packages/worker/src/api/routes/global/email.js index b771728a0f..962aea8d14 100644 --- a/packages/worker/src/api/routes/global/email.js +++ b/packages/worker/src/api/routes/global/email.js @@ -5,12 +5,20 @@ const { joiValidator } = require("@budibase/backend-core/auth") const { adminOnly } = require("@budibase/backend-core/auth") const Joi = require("joi") -const router = Router() +const router = new Router() function buildEmailSendValidation() { // prettier-ignore return joiValidator.body(Joi.object({ - email: Joi.string().email(), + email: Joi.string().email({ + multiple: true, + }), + cc: Joi.string().email({ + multiple: true, + }).allow("", null), + bcc: Joi.string().email({ + multiple: true, + }).allow("", null), purpose: Joi.string().valid(...Object.values(EmailTemplatePurpose)), workspaceId: Joi.string().allow("", null), from: Joi.string().allow("", null), diff --git a/packages/worker/src/api/routes/global/license.ts b/packages/worker/src/api/routes/global/license.ts index b9f5aa3218..03908e052b 100644 --- a/packages/worker/src/api/routes/global/license.ts +++ b/packages/worker/src/api/routes/global/license.ts @@ -7,6 +7,7 @@ router .post("/api/global/license/activate", controller.activate) .post("/api/global/license/refresh", controller.refresh) .get("/api/global/license/info", controller.getInfo) + .delete("/api/global/license/info", controller.deleteInfo) .get("/api/global/license/usage", controller.getQuotaUsage) export = router diff --git a/packages/worker/src/api/routes/global/roles.js b/packages/worker/src/api/routes/global/roles.js index d99e0e5b56..da7d5405ad 100644 --- a/packages/worker/src/api/routes/global/roles.js +++ b/packages/worker/src/api/routes/global/roles.js @@ -2,7 +2,7 @@ const Router = require("@koa/router") const controller = require("../../controllers/global/roles") const { builderOrAdmin } = require("@budibase/backend-core/auth") -const router = Router() +const router = new Router() router .get("/api/global/roles", builderOrAdmin, controller.fetch) diff --git a/packages/worker/src/api/routes/global/self.js b/packages/worker/src/api/routes/global/self.js deleted file mode 100644 index 1683a94f37..0000000000 --- a/packages/worker/src/api/routes/global/self.js +++ /dev/null @@ -1,18 +0,0 @@ -const Router = require("@koa/router") -const controller = require("../../controllers/global/self") -const { builderOnly } = require("@budibase/backend-core/auth") -const { users } = require("../validation") - -const router = Router() - -router - .post("/api/global/self/api_key", builderOnly, controller.generateAPIKey) - .get("/api/global/self/api_key", builderOnly, controller.fetchAPIKey) - .get("/api/global/self", controller.getSelf) - .post( - "/api/global/self", - users.buildUserSaveValidation(true), - controller.updateSelf - ) - -module.exports = router diff --git a/packages/worker/src/api/routes/global/self.ts b/packages/worker/src/api/routes/global/self.ts new file mode 100644 index 0000000000..4b52225783 --- /dev/null +++ b/packages/worker/src/api/routes/global/self.ts @@ -0,0 +1,18 @@ +import Router from "@koa/router" +import * as controller from "../../controllers/global/self" +import { auth } from "@budibase/backend-core" +import { users } from "../validation" + +const router = new Router() + +router + .post("/api/global/self/api_key", auth.builderOnly, controller.generateAPIKey) + .get("/api/global/self/api_key", auth.builderOnly, controller.fetchAPIKey) + .get("/api/global/self", controller.getSelf) + .post( + "/api/global/self", + users.buildUserSaveValidation(true), + controller.updateSelf + ) + +export default router as any diff --git a/packages/worker/src/api/routes/global/templates.js b/packages/worker/src/api/routes/global/templates.ts similarity index 72% rename from packages/worker/src/api/routes/global/templates.js rename to packages/worker/src/api/routes/global/templates.ts index 321e0543ad..2db9b5009e 100644 --- a/packages/worker/src/api/routes/global/templates.js +++ b/packages/worker/src/api/routes/global/templates.ts @@ -1,11 +1,11 @@ -const Router = require("@koa/router") -const controller = require("../../controllers/global/templates") -const { joiValidator } = require("@budibase/backend-core/auth") -const Joi = require("joi") -const { TemplatePurpose, TemplateTypes } = require("../../../constants") -const { adminOnly } = require("@budibase/backend-core/auth") +import Router from "@koa/router" +import * as controller from "../../controllers/global/templates" +import { TemplatePurpose, TemplateTypes } from "../../../constants" +import { auth as authCore } from "@budibase/backend-core" +import Joi from "joi" +const { adminOnly, joiValidator } = authCore -const router = Router() +const router = new Router() function buildTemplateSaveValidation() { // prettier-ignore @@ -34,4 +34,4 @@ router .get("/api/global/template/:id", controller.find) .delete("/api/global/template/:id/:rev", adminOnly, controller.destroy) -module.exports = router +export default router 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 fd9ef7ff9f..218bc60800 100644 --- a/packages/worker/src/api/routes/global/tests/users.spec.ts +++ b/packages/worker/src/api/routes/global/tests/users.spec.ts @@ -97,16 +97,16 @@ describe("/api/global/users", () => { }) }) - describe("bulkCreate", () => { + describe("bulk (create)", () => { it("should ignore users existing in the same tenant", async () => { const user = await config.createUser() jest.clearAllMocks() const response = await api.users.bulkCreateUsers([user]) - expect(response.successful.length).toBe(0) - expect(response.unsuccessful.length).toBe(1) - expect(response.unsuccessful[0].email).toBe(user.email) + expect(response.created?.successful.length).toBe(0) + expect(response.created?.unsuccessful.length).toBe(1) + expect(response.created?.unsuccessful[0].email).toBe(user.email) expect(events.user.created).toBeCalledTimes(0) }) @@ -117,9 +117,9 @@ describe("/api/global/users", () => { await tenancy.doInTenant(TENANT_1, async () => { const response = await api.users.bulkCreateUsers([user]) - expect(response.successful.length).toBe(0) - expect(response.unsuccessful.length).toBe(1) - expect(response.unsuccessful[0].email).toBe(user.email) + expect(response.created?.successful.length).toBe(0) + expect(response.created?.unsuccessful.length).toBe(1) + expect(response.created?.unsuccessful[0].email).toBe(user.email) expect(events.user.created).toBeCalledTimes(0) }) }) @@ -132,24 +132,24 @@ describe("/api/global/users", () => { const response = await api.users.bulkCreateUsers([user]) - expect(response.successful.length).toBe(0) - expect(response.unsuccessful.length).toBe(1) - expect(response.unsuccessful[0].email).toBe(user.email) + expect(response.created?.successful.length).toBe(0) + expect(response.created?.unsuccessful.length).toBe(1) + expect(response.created?.unsuccessful[0].email).toBe(user.email) expect(events.user.created).toBeCalledTimes(0) }) - it("should be able to bulkCreate users", async () => { + it("should be able to bulk create users", async () => { const builder = structures.users.builderUser() const admin = structures.users.adminUser() const user = structures.users.user() const response = await api.users.bulkCreateUsers([builder, admin, user]) - expect(response.successful.length).toBe(3) - expect(response.successful[0].email).toBe(builder.email) - expect(response.successful[1].email).toBe(admin.email) - expect(response.successful[2].email).toBe(user.email) - expect(response.unsuccessful.length).toBe(0) + expect(response.created?.successful.length).toBe(3) + expect(response.created?.successful[0].email).toBe(builder.email) + expect(response.created?.successful[1].email).toBe(admin.email) + expect(response.created?.successful[2].email).toBe(user.email) + expect(response.created?.unsuccessful.length).toBe(0) expect(events.user.created).toBeCalledTimes(3) expect(events.user.permissionAdminAssigned).toBeCalledTimes(1) expect(events.user.permissionBuilderAssigned).toBeCalledTimes(2) @@ -420,33 +420,30 @@ describe("/api/global/users", () => { }) }) - describe("bulkDelete", () => { - it("should not be able to bulkDelete current user", async () => { + describe("bulk (delete)", () => { + it("should not be able to bulk delete current user", async () => { const user = await config.defaultUser! - const request = { userIds: [user._id!] } - const response = await api.users.bulkDeleteUsers(request, 400) + const response = await api.users.bulkDeleteUsers([user._id!], 400) - expect(response.body.message).toBe("Unable to delete self.") + expect(response.message).toBe("Unable to delete self.") expect(events.user.deleted).not.toBeCalled() }) - it("should not be able to bulkDelete account owner", async () => { + it("should not be able to bulk delete account owner", async () => { const user = await config.createUser() const account = structures.accounts.cloudAccount() account.budibaseUserId = user._id! mocks.accounts.getAccountByTenantId.mockReturnValue(account) - const request = { userIds: [user._id!] } + const response = await api.users.bulkDeleteUsers([user._id!]) - const response = await api.users.bulkDeleteUsers(request) - - expect(response.body.successful.length).toBe(0) - expect(response.body.unsuccessful.length).toBe(1) - expect(response.body.unsuccessful[0].reason).toBe( + expect(response.deleted?.successful.length).toBe(0) + expect(response.deleted?.unsuccessful.length).toBe(1) + expect(response.deleted?.unsuccessful[0].reason).toBe( "Account holder cannot be deleted" ) - expect(response.body.unsuccessful[0]._id).toBe(user._id) + expect(response.deleted?.unsuccessful[0]._id).toBe(user._id) expect(events.user.deleted).not.toBeCalled() }) @@ -462,12 +459,14 @@ describe("/api/global/users", () => { admin, user, ]) - const request = { userIds: createdUsers.successful.map(u => u._id!) } - const response = await api.users.bulkDeleteUsers(request) + const toDelete = createdUsers.created?.successful.map( + u => u._id! + ) as string[] + const response = await api.users.bulkDeleteUsers(toDelete) - expect(response.body.successful.length).toBe(3) - expect(response.body.unsuccessful.length).toBe(0) + expect(response.deleted?.successful.length).toBe(3) + expect(response.deleted?.unsuccessful.length).toBe(0) expect(events.user.deleted).toBeCalledTimes(3) expect(events.user.permissionAdminRemoved).toBeCalledTimes(1) expect(events.user.permissionBuilderRemoved).toBeCalledTimes(2) diff --git a/packages/worker/src/api/routes/global/users.js b/packages/worker/src/api/routes/global/users.js index e0a221a795..2d9b1d9ac9 100644 --- a/packages/worker/src/api/routes/global/users.js +++ b/packages/worker/src/api/routes/global/users.js @@ -8,7 +8,7 @@ const { users } = require("../validation") const selfController = require("../../controllers/global/self") const { builderOrAdmin } = require("@budibase/backend-core/auth") -const router = Router() +const router = new Router() function buildAdminInitValidation() { return joiValidator.body( @@ -56,16 +56,15 @@ router controller.save ) .post( - "/api/global/users/bulkCreate", + "/api/global/users/bulk", adminOnly, - users.buildUserBulkSaveValidation(), - controller.bulkCreate + users.buildUserBulkUserValidation(), + controller.bulkUpdate ) .get("/api/global/users", builderOrAdmin, controller.fetch) .post("/api/global/users/search", builderOrAdmin, controller.search) .delete("/api/global/users/:id", adminOnly, controller.destroy) - .post("/api/global/users/bulkDelete", adminOnly, controller.bulkDelete) .get("/api/global/users/count/:appId", builderOrAdmin, controller.countByApp) .get("/api/global/roles/:appId") .post( @@ -74,12 +73,6 @@ router buildInviteValidation(), controller.invite ) - .post( - "/api/global/users/invite", - adminOnly, - buildInviteValidation(), - controller.invite - ) .post( "/api/global/users/multi/invite", adminOnly, diff --git a/packages/worker/src/api/routes/global/workspaces.js b/packages/worker/src/api/routes/global/workspaces.js index 0198991bfa..c0e172cd8d 100644 --- a/packages/worker/src/api/routes/global/workspaces.js +++ b/packages/worker/src/api/routes/global/workspaces.js @@ -4,7 +4,7 @@ const { joiValidator } = require("@budibase/backend-core/auth") const { adminOnly } = require("@budibase/backend-core/auth") const Joi = require("joi") -const router = Router() +const router = new Router() function buildWorkspaceSaveValidation() { // prettier-ignore diff --git a/packages/worker/src/api/routes/index.js b/packages/worker/src/api/routes/index.js deleted file mode 100644 index 7f5c783caa..0000000000 --- a/packages/worker/src/api/routes/index.js +++ /dev/null @@ -1,34 +0,0 @@ -const { api } = require("@budibase/pro") -const userRoutes = require("./global/users") -const configRoutes = require("./global/configs") -const workspaceRoutes = require("./global/workspaces") -const templateRoutes = require("./global/templates") -const emailRoutes = require("./global/email") -const authRoutes = require("./global/auth") -const roleRoutes = require("./global/roles") -const environmentRoutes = require("./system/environment") -const tenantsRoutes = require("./system/tenants") -const statusRoutes = require("./system/status") -const selfRoutes = require("./global/self") -const licenseRoutes = require("./global/license") -const migrationRoutes = require("./system/migrations") -const accountRoutes = require("./system/accounts") - -let userGroupRoutes = api.groups -exports.routes = [ - configRoutes, - userRoutes, - workspaceRoutes, - authRoutes, - templateRoutes, - tenantsRoutes, - emailRoutes, - roleRoutes, - environmentRoutes, - statusRoutes, - selfRoutes, - licenseRoutes, - userGroupRoutes, - migrationRoutes, - accountRoutes, -] diff --git a/packages/worker/src/api/routes/index.ts b/packages/worker/src/api/routes/index.ts new file mode 100644 index 0000000000..67edf5d51b --- /dev/null +++ b/packages/worker/src/api/routes/index.ts @@ -0,0 +1,34 @@ +import { api } from "@budibase/pro" +import userRoutes from "./global/users" +import configRoutes from "./global/configs" +import workspaceRoutes from "./global/workspaces" +import templateRoutes from "./global/templates" +import emailRoutes from "./global/email" +import authRoutes from "./global/auth" +import roleRoutes from "./global/roles" +import environmentRoutes from "./system/environment" +import tenantsRoutes from "./system/tenants" +import statusRoutes from "./system/status" +import selfRoutes from "./global/self" +import licenseRoutes from "./global/license" +import migrationRoutes from "./system/migrations" +import accountRoutes from "./system/accounts" + +let userGroupRoutes = api.groups +export const routes = [ + configRoutes, + userRoutes, + workspaceRoutes, + authRoutes, + templateRoutes, + tenantsRoutes, + emailRoutes, + roleRoutes, + environmentRoutes, + statusRoutes, + selfRoutes, + licenseRoutes, + userGroupRoutes, + migrationRoutes, + accountRoutes, +] diff --git a/packages/worker/src/api/routes/system/environment.js b/packages/worker/src/api/routes/system/environment.js index 9b1b85638f..3d34046317 100644 --- a/packages/worker/src/api/routes/system/environment.js +++ b/packages/worker/src/api/routes/system/environment.js @@ -1,7 +1,7 @@ const Router = require("@koa/router") const controller = require("../../controllers/system/environment") -const router = Router() +const router = new Router() router.get("/api/system/environment", controller.fetch) diff --git a/packages/worker/src/api/routes/system/status.js b/packages/worker/src/api/routes/system/status.js index a39801375b..17d2f8a5a6 100644 --- a/packages/worker/src/api/routes/system/status.js +++ b/packages/worker/src/api/routes/system/status.js @@ -1,7 +1,7 @@ const Router = require("@koa/router") const controller = require("../../controllers/system/status") -const router = Router() +const router = new Router() router.get("/api/system/status", controller.fetch) diff --git a/packages/worker/src/api/routes/system/tenants.js b/packages/worker/src/api/routes/system/tenants.js index 451f09f773..6247e76058 100644 --- a/packages/worker/src/api/routes/system/tenants.js +++ b/packages/worker/src/api/routes/system/tenants.js @@ -2,7 +2,7 @@ const Router = require("@koa/router") const controller = require("../../controllers/system/tenants") const { adminOnly } = require("@budibase/backend-core/auth") -const router = Router() +const router = new Router() router .get("/api/system/tenants/:tenantId/exists", controller.exists) diff --git a/packages/worker/src/api/routes/system/tests/accounts.spec.ts b/packages/worker/src/api/routes/system/tests/accounts.spec.ts index e3a6141cb7..f977d22cd9 100644 --- a/packages/worker/src/api/routes/system/tests/accounts.spec.ts +++ b/packages/worker/src/api/routes/system/tests/accounts.spec.ts @@ -1,4 +1,4 @@ -import { accounts } from "../../../../sdk" +import sdk from "../../../../sdk" import { TestConfiguration, structures, API } from "../../../../tests" import { v4 as uuid } from "uuid" @@ -25,8 +25,8 @@ describe("accounts", () => { const response = await api.accounts.saveMetadata(account) - const id = accounts.formatAccountMetadataId(account.accountId) - const metadata = await accounts.getMetadata(id) + const id = sdk.accounts.formatAccountMetadataId(account.accountId) + const metadata = await sdk.accounts.getMetadata(id) expect(response).toStrictEqual(metadata) }) }) @@ -38,7 +38,7 @@ describe("accounts", () => { await api.accounts.destroyMetadata(account.accountId) - const deleted = await accounts.getMetadata(account.accountId) + const deleted = await sdk.accounts.getMetadata(account.accountId) expect(deleted).toBe(undefined) }) diff --git a/packages/worker/src/api/routes/validation/users.ts b/packages/worker/src/api/routes/validation/users.ts index d84ae94ee6..0cb14c047e 100644 --- a/packages/worker/src/api/routes/validation/users.ts +++ b/packages/worker/src/api/routes/validation/users.ts @@ -28,7 +28,7 @@ export const buildUserSaveValidation = (isSelf = false) => { return joiValidator.body(Joi.object(schema).required().unknown(true)) } -export const buildUserBulkSaveValidation = (isSelf = false) => { +export const buildUserBulkUserValidation = (isSelf = false) => { if (!isSelf) { schema = { ...schema, @@ -36,10 +36,15 @@ export const buildUserBulkSaveValidation = (isSelf = false) => { _rev: Joi.string(), } } - let bulkSaveSchema = { - groups: Joi.array().optional(), - users: Joi.array().items(Joi.object(schema).required().unknown(true)), + let bulkSchema = { + create: Joi.object({ + groups: Joi.array().optional(), + users: Joi.array().items(Joi.object(schema).required().unknown(true)), + }), + delete: Joi.object({ + userIds: Joi.array().items(Joi.string()), + }), } - return joiValidator.body(Joi.object(bulkSaveSchema).required().unknown(true)) + return joiValidator.body(Joi.object(bulkSchema).required().unknown(true)) } diff --git a/packages/worker/src/db/index.js b/packages/worker/src/db/index.js index 25dc02962b..58fd8484ff 100644 --- a/packages/worker/src/db/index.js +++ b/packages/worker/src/db/index.js @@ -3,7 +3,7 @@ const env = require("../environment") exports.init = () => { const dbConfig = {} - if (env.isTest()) { + if (env.isTest() && !env.COUCH_DB_URL) { dbConfig.inMemory = true dbConfig.allDbs = true } diff --git a/packages/worker/src/migrations/functions/globalInfoSyncUsers.ts b/packages/worker/src/migrations/functions/globalInfoSyncUsers.ts index cae6c6af51..941791fe93 100644 --- a/packages/worker/src/migrations/functions/globalInfoSyncUsers.ts +++ b/packages/worker/src/migrations/functions/globalInfoSyncUsers.ts @@ -1,5 +1,5 @@ import { User } from "@budibase/types" -import * as sdk from "../../sdk" +import sdk from "../../sdk" /** * Date: diff --git a/packages/worker/src/sdk/index.ts b/packages/worker/src/sdk/index.ts index fdc1098361..5febb7ba3c 100644 --- a/packages/worker/src/sdk/index.ts +++ b/packages/worker/src/sdk/index.ts @@ -1,2 +1,7 @@ -export * as users from "./users" -export * as accounts from "./accounts" +import * as users from "./users" +import * as accounts from "./accounts" + +export default { + users, + accounts, +} diff --git a/packages/worker/src/sdk/users/users.ts b/packages/worker/src/sdk/users/users.ts index 4e030f5e61..775514ea5e 100644 --- a/packages/worker/src/sdk/users/users.ts +++ b/packages/worker/src/sdk/users/users.ts @@ -19,9 +19,7 @@ import { import { AccountMetadata, AllDocsResponse, - BulkCreateUsersResponse, - BulkDeleteUsersResponse, - BulkDocsResponse, + BulkUserResponse, CloudAccount, CreateUserResponse, InviteUsersRequest, @@ -31,9 +29,9 @@ import { RowResponse, User, } from "@budibase/types" -import { groups as groupUtils } from "@budibase/pro" import { sendEmail } from "../../utilities/email" import { EmailTemplatePurpose } from "../../constants" +import { groups as groupsSdk } from "@budibase/pro" const PAGE_LIMIT = 8 @@ -349,8 +347,7 @@ const searchExistingEmails = async (emails: string[]) => { export const bulkCreate = async ( newUsersRequested: User[], groups: string[] -): Promise => { - const db = tenancy.getGlobalDB() +): Promise => { const tenantId = tenancy.getTenantId() let usersToSave: any[] = [] @@ -392,9 +389,9 @@ export const bulkCreate = async ( }) const usersToBulkSave = await Promise.all(usersToSave) - await db.bulkDocs(usersToBulkSave) + await usersCore.bulkUpdateGlobalUsers(usersToBulkSave) - // Post processing of bulk added users, i.e events and cache operations + // Post-processing of bulk added users, e.g. events and cache operations for (const user of usersToBulkSave) { // TODO: Refactor to bulk insert users into the info db // instead of relying on looping tenant creation @@ -410,6 +407,16 @@ export const bulkCreate = async ( } }) + // now update the groups + if (Array.isArray(saved) && groups) { + const groupPromises = [] + const createdUserIds = saved.map(user => user._id) + for (let groupId of groups) { + groupPromises.push(groupsSdk.addUsers(groupId, createdUserIds)) + } + await Promise.all(groupPromises) + } + return { successful: saved, unsuccessful, @@ -438,10 +445,10 @@ const getAccountHolderFromUserIds = async ( export const bulkDelete = async ( userIds: string[] -): Promise => { +): Promise => { const db = tenancy.getGlobalDB() - const response: BulkDeleteUsersResponse = { + const response: BulkUserResponse["deleted"] = { successful: [], unsuccessful: [], } @@ -458,7 +465,6 @@ export const bulkDelete = async ( }) } - let groupsToModify: any = {} // Get users and delete const allDocsResponse: AllDocsResponse = await db.allDocs({ include_docs: true, @@ -466,33 +472,16 @@ export const bulkDelete = async ( }) const usersToDelete: User[] = allDocsResponse.rows.map( (user: RowResponse) => { - // if we find a user that has an associated group, add it to - // an array so we can easily use allDocs on them later. - // This prevents us having to re-loop over all the users - if (user.doc.userGroups) { - for (let groupId of user.doc.userGroups) { - if (!Object.keys(groupsToModify).includes(groupId)) { - groupsToModify[groupId] = [user.id] - } else { - groupsToModify[groupId] = [...groupsToModify[groupId], user.id] - } - } - } - return user.doc } ) // Delete from DB - const dbResponse: BulkDocsResponse = await db.bulkDocs( - usersToDelete.map(user => ({ - ...user, - _deleted: true, - })) - ) - - // Deletion post processing - await groupUtils.bulkDeleteGroupUsers(groupsToModify) + const toDelete = usersToDelete.map(user => ({ + ...user, + _deleted: true, + })) + const dbResponse = await usersCore.bulkUpdateGlobalUsers(toDelete) for (let user of usersToDelete) { await bulkDeleteProcessing(user) } @@ -526,7 +515,6 @@ export const destroy = async (id: string, currentUser: any) => { const db = tenancy.getGlobalDB() const dbUser = await db.get(id) const userId = dbUser._id as string - let groups = dbUser.userGroups if (!env.SELF_HOSTED && !env.DISABLE_ACCOUNT_PORTAL) { // root account holder can't be deleted from inside budibase @@ -545,10 +533,6 @@ export const destroy = async (id: string, currentUser: any) => { await db.remove(userId, dbUser._rev) - if (groups) { - await groupUtils.deleteGroupUsers(groups, dbUser) - } - await eventHelpers.handleDeleteEvents(dbUser) await cache.user.invalidateUser(userId) await sessions.invalidateSessions(userId, { reason: "deletion" }) diff --git a/packages/worker/src/tests/api/users.ts b/packages/worker/src/tests/api/users.ts index 986a26ad5f..3677bfffc6 100644 --- a/packages/worker/src/tests/api/users.ts +++ b/packages/worker/src/tests/api/users.ts @@ -1,8 +1,6 @@ import { - BulkCreateUsersRequest, - BulkCreateUsersResponse, - BulkDeleteUsersRequest, - BulkDeleteUsersResponse, + BulkUserResponse, + BulkUserRequest, InviteUsersRequest, User, } from "@budibase/types" @@ -69,24 +67,26 @@ export class UserAPI { // BULK bulkCreateUsers = async (users: User[], groups: any[] = []) => { - const body: BulkCreateUsersRequest = { users, groups } + const body: BulkUserRequest = { create: { users, groups } } const res = await this.request - .post(`/api/global/users/bulkCreate`) + .post(`/api/global/users/bulk`) .send(body) .set(this.config.defaultHeaders()) .expect("Content-Type", /json/) .expect(200) - return res.body as BulkCreateUsersResponse + return res.body as BulkUserResponse } - bulkDeleteUsers = (body: BulkDeleteUsersRequest, status?: number) => { - return this.request - .post(`/api/global/users/bulkDelete`) + bulkDeleteUsers = async (userIds: string[], status?: number) => { + const body: BulkUserRequest = { delete: { userIds } } + const res = await this.request + .post(`/api/global/users/bulk`) .send(body) .set(this.config.defaultHeaders()) .expect("Content-Type", /json/) .expect(status ? status : 200) + return res.body as BulkUserResponse } // USER diff --git a/packages/worker/src/utilities/email.js b/packages/worker/src/utilities/email.js index 06b1ea851c..66f78bb543 100644 --- a/packages/worker/src/utilities/email.js +++ b/packages/worker/src/utilities/email.js @@ -174,7 +174,7 @@ exports.isEmailConfigured = async (workspaceId = null) => { exports.sendEmail = async ( email, purpose, - { workspaceId, user, from, contents, subject, info, automation } = {} + { workspaceId, user, from, contents, subject, info, cc, bcc, automation } = {} ) => { const db = getGlobalDB() let config = (await getSmtpConfiguration(db, workspaceId, automation)) || {} @@ -197,6 +197,8 @@ exports.sendEmail = async ( message = { ...message, to: email, + cc: cc, + bcc: bcc, } if (subject || config.subject) { diff --git a/packages/worker/yarn.lock b/packages/worker/yarn.lock index f9b44af49f..eff2a655de 100644 --- a/packages/worker/yarn.lock +++ b/packages/worker/yarn.lock @@ -291,12 +291,12 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@1.4.17": - version "1.4.17" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.4.17.tgz#680e2de7cc4cb598c29438cc00207cb0f8750555" - integrity sha512-e4ahZnPnRXTFohD17pkDO1uxP44elbH2RFpvHodQ+jzOQPwi3NWAKi7+3BbagRzoLv7Q9Mq8IhIBZrYLntKS6g== +"@budibase/backend-core@1.4.18-alpha.0": + version "1.4.18-alpha.0" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.4.18-alpha.0.tgz#27c77d0c28a17a2ee67ad0ada1431f4f03e34747" + integrity sha512-eP7v7MaULTi8ieWo0qHuXH8E2wv+8C+2FOdc4ah/af+MFP2lslfhlwF5X6aSkzODV9KbaQr1by0ytM7QS+nH6A== dependencies: - "@budibase/types" "^1.4.17" + "@budibase/types" "1.4.18-alpha.0" "@shopify/jest-koa-mocks" "5.0.1" "@techpass/passport-openidconnect" "0.3.2" aws-sdk "2.1030.0" @@ -327,21 +327,21 @@ uuid "8.3.2" zlib "1.0.5" -"@budibase/pro@1.4.17": - version "1.4.17" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.4.17.tgz#0648965741e77597a216806aa7e1b71212c87cc1" - integrity sha512-2ug6e8dKntOW9Fmxnr++76eV/n7CXlEfUnbVyQM8vixofCPTFBQ1mL6nAg1Cc4dx6x8grhb2o5OIydhgv0bVSQ== +"@budibase/pro@1.4.18-alpha.0": + version "1.4.18-alpha.0" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.4.18-alpha.0.tgz#e9910569a769e5ce107f8200ccba5295dc365fa0" + integrity sha512-GsWDZb1H3Cm3vhY8n5+eekS14pjJRI7SRDt838ff4ECLpTp6YSVnOkIwms8g7uQUuXa8HbSBDl50W93wTR4QdQ== dependencies: - "@budibase/backend-core" "1.4.17" - "@budibase/types" "1.4.17" + "@budibase/backend-core" "1.4.18-alpha.0" + "@budibase/types" "1.4.18-alpha.0" "@koa/router" "8.0.8" joi "17.6.0" node-fetch "^2.6.1" -"@budibase/types@1.4.17", "@budibase/types@^1.4.17": - version "1.4.17" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-1.4.17.tgz#ca71fcfe202856d15fe25110edf76d81978a7dd1" - integrity sha512-JDJVx/OkvfZmH2z4rqc7qx/XyDiL/DfgGS5U+pHqQXdxO+OapfoT/Lj/X3afnvlzN/lg2h8IERLU2Ns81D2DIw== +"@budibase/types@1.4.18-alpha.0": + version "1.4.18-alpha.0" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-1.4.18-alpha.0.tgz#f1abbef32395659ba53176fdd485557fb0f66487" + integrity sha512-UIjVotIUzu4v9IVzqEzwQdusyr5bxfET89bZ2+mTeUIj5xzWmS6z4vlBlDv2nfZThFKvXDXE5YFgzSGdESBIrA== "@cspotcode/source-map-consumer@0.8.0": version "0.8.0" diff --git a/qa-core/.env b/qa-core/.env index 740b1b2b2a..36dd0a3656 100644 --- a/qa-core/.env +++ b/qa-core/.env @@ -1,3 +1,6 @@ BB_ADMIN_USER_EMAIL=qa@budibase.com BB_ADMIN_USER_PASSWORD=budibase ENCRYPTED_TEST_PUBLIC_API_KEY=a65722f06bee5caeadc5d7ca2f543a43-d610e627344210c643bb726f +COUCH_DB_URL=http://budibase:budibase@localhost:4567 +COUCH_DB_USER=budibase +COUCH_DB_PASSWORD=budibase \ No newline at end of file diff --git a/qa-core/docker-compose.yaml b/qa-core/docker-compose.yaml new file mode 100644 index 0000000000..abd8e4818e --- /dev/null +++ b/qa-core/docker-compose.yaml @@ -0,0 +1,12 @@ +version: "3.8" +services: + qa-core-couchdb: + # platform: linux/amd64 + container_name: budi-couchdb-qa + restart: on-failure + image: ibmcom/couchdb3 + environment: + - COUCHDB_PASSWORD=${COUCH_DB_PASSWORD} + - COUCHDB_USER=${COUCH_DB_USER} + ports: + - "4567:5984" diff --git a/qa-core/package.json b/qa-core/package.json index b2c3f464d7..529827bc9f 100644 --- a/qa-core/package.json +++ b/qa-core/package.json @@ -12,7 +12,9 @@ "test": "jest --runInBand", "test:watch": "jest --watch", "test:debug": "DEBUG=1 jest", - "api:server:setup": "env-cmd ts-node ../packages/builder/cypress/ts/setup.ts", + "docker:up": "docker-compose up -d", + "docker:down": "docker-compose down", + "api:server:setup": "npm run docker:up && env-cmd ts-node ../packages/builder/cypress/ts/setup.ts", "api:server:setup:ci": "env-cmd node ../packages/builder/cypress/setup.js", "api:test:ci": "start-server-and-test api:server:setup:ci http://localhost:4100/builder test", "api:test": "start-server-and-test api:server:setup http://localhost:4100/builder test" diff --git a/qa-core/src/tests/public-api/tables/rows.spec.ts b/qa-core/src/tests/public-api/tables/rows.spec.ts index 38a813b093..89149159ab 100644 --- a/qa-core/src/tests/public-api/tables/rows.spec.ts +++ b/qa-core/src/tests/public-api/tables/rows.spec.ts @@ -32,8 +32,7 @@ describe("Public API - /rows endpoints", () => { expect(row._id).toBeDefined() }) - // search really isn't supported - xit("POST - Search rows", async () => { + it("POST - Search rows", async () => { const [response, rows] = await config.rows.search({ query: { string: { @@ -42,6 +41,7 @@ describe("Public API - /rows endpoints", () => { }, }) expect(response).toHaveStatusCode(200) + expect(rows.length).toEqual(1) expect(rows[0]._id).toEqual(config.context._id) expect(rows[0].tableId).toEqual(config.context.tableId) expect(rows[0].testColumn).toEqual(config.context.testColumn)