merge
This commit is contained in:
commit
57cf6dec94
|
@ -16,8 +16,8 @@ jobs:
|
|||
days-before-pr-stale: 7
|
||||
stale-issue-label: stale
|
||||
exempt-pr-labels: pinned,security,roadmap
|
||||
|
||||
days-before-pr-close: 7
|
||||
days-before-issue-close: 30
|
||||
|
||||
- uses: actions/stale@v8
|
||||
with:
|
||||
|
@ -26,6 +26,7 @@ jobs:
|
|||
days-before-stale: 30
|
||||
only-issue-labels: bug,High priority
|
||||
stale-issue-label: warn
|
||||
days-before-close: 30
|
||||
|
||||
- uses: actions/stale@v8
|
||||
with:
|
||||
|
@ -34,6 +35,7 @@ jobs:
|
|||
days-before-stale: 90
|
||||
only-issue-labels: bug,Medium priority
|
||||
stale-issue-label: warn
|
||||
days-before-close: 30
|
||||
|
||||
- uses: actions/stale@v8
|
||||
with:
|
||||
|
@ -43,5 +45,4 @@ jobs:
|
|||
stale-issue-label: stale
|
||||
only-issue-labels: bug
|
||||
stale-issue-message: "This issue has been automatically marked as stale because it has not had any activity for six months."
|
||||
|
||||
days-before-close: 30
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": "2.13.50",
|
||||
"version": "2.13.52",
|
||||
"npmClient": "yarn",
|
||||
"packages": [
|
||||
"packages/*",
|
||||
|
|
|
@ -18,14 +18,15 @@ export enum TTL {
|
|||
ONE_DAY = 86400,
|
||||
}
|
||||
|
||||
function performExport(funcName: string) {
|
||||
// @ts-ignore
|
||||
return (...args: any) => GENERIC[funcName](...args)
|
||||
}
|
||||
|
||||
export const keys = performExport("keys")
|
||||
export const get = performExport("get")
|
||||
export const store = performExport("store")
|
||||
export const destroy = performExport("delete")
|
||||
export const withCache = performExport("withCache")
|
||||
export const bustCache = performExport("bustCache")
|
||||
export const keys = (...args: Parameters<typeof GENERIC.keys>) =>
|
||||
GENERIC.keys(...args)
|
||||
export const get = (...args: Parameters<typeof GENERIC.get>) =>
|
||||
GENERIC.get(...args)
|
||||
export const store = (...args: Parameters<typeof GENERIC.store>) =>
|
||||
GENERIC.store(...args)
|
||||
export const destroy = (...args: Parameters<typeof GENERIC.delete>) =>
|
||||
GENERIC.delete(...args)
|
||||
export const withCache = (...args: Parameters<typeof GENERIC.withCache>) =>
|
||||
GENERIC.withCache(...args)
|
||||
export const bustCache = (...args: Parameters<typeof GENERIC.bustCache>) =>
|
||||
GENERIC.bustCache(...args)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as redis from "../redis/init"
|
||||
import * as utils from "../utils"
|
||||
import { Duration, DurationType } from "../utils"
|
||||
import { Duration } from "../utils"
|
||||
|
||||
const TTL_SECONDS = Duration.fromHours(1).toSeconds()
|
||||
|
||||
|
@ -32,7 +32,18 @@ export async function getCode(code: string): Promise<PasswordReset> {
|
|||
const client = await redis.getPasswordResetClient()
|
||||
const value = (await client.get(code)) as PasswordReset | undefined
|
||||
if (!value) {
|
||||
throw "Provided information is not valid, cannot reset password - please try again."
|
||||
throw new Error(
|
||||
"Provided information is not valid, cannot reset password - please try again."
|
||||
)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a reset code this will invalidate it.
|
||||
* @param code The code provided via the email link.
|
||||
*/
|
||||
export async function invalidateCode(code: string): Promise<void> {
|
||||
const client = await redis.getPasswordResetClient()
|
||||
await client.delete(code)
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import { directCouchUrlCall } from "./utils"
|
|||
import { getPouchDB } from "./pouchDB"
|
||||
import { WriteStream, ReadStream } from "fs"
|
||||
import { newid } from "../../docIds/newid"
|
||||
import { DDInstrumentedDatabase } from "../instrumentation"
|
||||
|
||||
function buildNano(couchInfo: { url: string; cookie: string }) {
|
||||
return Nano({
|
||||
|
@ -35,7 +36,8 @@ export function DatabaseWithConnection(
|
|||
connection: string,
|
||||
opts?: DatabaseOpts
|
||||
) {
|
||||
return new DatabaseImpl(dbName, opts, connection)
|
||||
const db = new DatabaseImpl(dbName, opts, connection)
|
||||
return new DDInstrumentedDatabase(db)
|
||||
}
|
||||
|
||||
export class DatabaseImpl implements Database {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { directCouchQuery, DatabaseImpl } from "./couch"
|
||||
import { CouchFindOptions, Database, DatabaseOpts } from "@budibase/types"
|
||||
import { DDInstrumentedDatabase } from "./instrumentation"
|
||||
|
||||
export function getDB(dbName: string, opts?: DatabaseOpts): Database {
|
||||
return new DatabaseImpl(dbName, opts)
|
||||
return new DDInstrumentedDatabase(new DatabaseImpl(dbName, opts))
|
||||
}
|
||||
|
||||
// we have to use a callback for this so that we can close
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
import {
|
||||
DocumentScope,
|
||||
DocumentDestroyResponse,
|
||||
DocumentInsertResponse,
|
||||
DocumentBulkResponse,
|
||||
OkResponse,
|
||||
} from "@budibase/nano"
|
||||
import {
|
||||
AllDocsResponse,
|
||||
AnyDocument,
|
||||
Database,
|
||||
DatabaseDumpOpts,
|
||||
DatabasePutOpts,
|
||||
DatabaseQueryOpts,
|
||||
Document,
|
||||
} from "@budibase/types"
|
||||
import tracer from "dd-trace"
|
||||
import { Writable } from "stream"
|
||||
|
||||
export class DDInstrumentedDatabase implements Database {
|
||||
constructor(private readonly db: Database) {}
|
||||
|
||||
get name(): string {
|
||||
return this.db.name
|
||||
}
|
||||
|
||||
exists(): Promise<boolean> {
|
||||
return tracer.trace("db.exists", span => {
|
||||
span?.addTags({ db_name: this.name })
|
||||
return this.db.exists()
|
||||
})
|
||||
}
|
||||
|
||||
checkSetup(): Promise<DocumentScope<any>> {
|
||||
return tracer.trace("db.checkSetup", span => {
|
||||
span?.addTags({ db_name: this.name })
|
||||
return this.db.checkSetup()
|
||||
})
|
||||
}
|
||||
|
||||
get<T extends Document>(id?: string | undefined): Promise<T> {
|
||||
return tracer.trace("db.get", span => {
|
||||
span?.addTags({ db_name: this.name, doc_id: id })
|
||||
return this.db.get(id)
|
||||
})
|
||||
}
|
||||
|
||||
getMultiple<T extends Document>(
|
||||
ids: string[],
|
||||
opts?: { allowMissing?: boolean | undefined } | undefined
|
||||
): Promise<T[]> {
|
||||
return tracer.trace("db.getMultiple", span => {
|
||||
span?.addTags({
|
||||
db_name: this.name,
|
||||
num_docs: ids.length,
|
||||
allow_missing: opts?.allowMissing,
|
||||
})
|
||||
return this.db.getMultiple(ids, opts)
|
||||
})
|
||||
}
|
||||
|
||||
remove(
|
||||
id: string | Document,
|
||||
rev?: string | undefined
|
||||
): Promise<DocumentDestroyResponse> {
|
||||
return tracer.trace("db.remove", span => {
|
||||
span?.addTags({ db_name: this.name, doc_id: id })
|
||||
return this.db.remove(id, rev)
|
||||
})
|
||||
}
|
||||
|
||||
put(
|
||||
document: AnyDocument,
|
||||
opts?: DatabasePutOpts | undefined
|
||||
): Promise<DocumentInsertResponse> {
|
||||
return tracer.trace("db.put", span => {
|
||||
span?.addTags({ db_name: this.name, doc_id: document._id })
|
||||
return this.db.put(document, opts)
|
||||
})
|
||||
}
|
||||
|
||||
bulkDocs(documents: AnyDocument[]): Promise<DocumentBulkResponse[]> {
|
||||
return tracer.trace("db.bulkDocs", span => {
|
||||
span?.addTags({ db_name: this.name, num_docs: documents.length })
|
||||
return this.db.bulkDocs(documents)
|
||||
})
|
||||
}
|
||||
|
||||
allDocs<T extends Document>(
|
||||
params: DatabaseQueryOpts
|
||||
): Promise<AllDocsResponse<T>> {
|
||||
return tracer.trace("db.allDocs", span => {
|
||||
span?.addTags({ db_name: this.name })
|
||||
return this.db.allDocs(params)
|
||||
})
|
||||
}
|
||||
|
||||
query<T extends Document>(
|
||||
viewName: string,
|
||||
params: DatabaseQueryOpts
|
||||
): Promise<AllDocsResponse<T>> {
|
||||
return tracer.trace("db.query", span => {
|
||||
span?.addTags({ db_name: this.name, view_name: viewName })
|
||||
return this.db.query(viewName, params)
|
||||
})
|
||||
}
|
||||
|
||||
destroy(): Promise<void | OkResponse> {
|
||||
return tracer.trace("db.destroy", span => {
|
||||
span?.addTags({ db_name: this.name })
|
||||
return this.db.destroy()
|
||||
})
|
||||
}
|
||||
|
||||
compact(): Promise<void | OkResponse> {
|
||||
return tracer.trace("db.compact", span => {
|
||||
span?.addTags({ db_name: this.name })
|
||||
return this.db.compact()
|
||||
})
|
||||
}
|
||||
|
||||
dump(stream: Writable, opts?: DatabaseDumpOpts | undefined): Promise<any> {
|
||||
return tracer.trace("db.dump", span => {
|
||||
span?.addTags({ db_name: this.name })
|
||||
return this.db.dump(stream, opts)
|
||||
})
|
||||
}
|
||||
|
||||
load(...args: any[]): Promise<any> {
|
||||
return tracer.trace("db.load", span => {
|
||||
span?.addTags({ db_name: this.name })
|
||||
return this.db.load(...args)
|
||||
})
|
||||
}
|
||||
|
||||
createIndex(...args: any[]): Promise<any> {
|
||||
return tracer.trace("db.createIndex", span => {
|
||||
span?.addTags({ db_name: this.name })
|
||||
return this.db.createIndex(...args)
|
||||
})
|
||||
}
|
||||
|
||||
deleteIndex(...args: any[]): Promise<any> {
|
||||
return tracer.trace("db.deleteIndex", span => {
|
||||
span?.addTags({ db_name: this.name })
|
||||
return this.db.deleteIndex(...args)
|
||||
})
|
||||
}
|
||||
|
||||
getIndexes(...args: any[]): Promise<any> {
|
||||
return tracer.trace("db.getIndexes", span => {
|
||||
span?.addTags({ db_name: this.name })
|
||||
return this.db.getIndexes(...args)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import { IdentityType } from "@budibase/types"
|
|||
import env from "../../environment"
|
||||
import * as context from "../../context"
|
||||
import * as correlation from "../correlation"
|
||||
import tracer from "dd-trace"
|
||||
import { formats } from "dd-trace/ext"
|
||||
|
||||
import { localFileDestination } from "../system"
|
||||
|
@ -116,6 +117,11 @@ if (!env.DISABLE_PINO_LOGGER) {
|
|||
correlationId: correlation.getId(),
|
||||
}
|
||||
|
||||
const span = tracer.scope().active()
|
||||
if (span) {
|
||||
tracer.inject(span.context(), formats.LOG, contextObject)
|
||||
}
|
||||
|
||||
const mergingObject: any = {
|
||||
err: error,
|
||||
pid: process.pid,
|
||||
|
|
|
@ -47,7 +47,7 @@ export function createQueue<T>(
|
|||
cleanupInterval = timers.set(cleanup, CLEANUP_PERIOD_MS)
|
||||
// fire off an initial cleanup
|
||||
cleanup().catch(err => {
|
||||
console.error(`Unable to cleanup automation queue initially - ${err}`)
|
||||
console.error(`Unable to cleanup ${jobQueue} initially - ${err}`)
|
||||
})
|
||||
}
|
||||
return queue
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
SelectableDatabase,
|
||||
getRedisConnectionDetails,
|
||||
} from "./utils"
|
||||
import { logAlert } from "../logging"
|
||||
import * as timers from "../timers"
|
||||
|
||||
const RETRY_PERIOD_MS = 2000
|
||||
|
@ -39,21 +40,16 @@ function pickClient(selectDb: number): any {
|
|||
return CLIENTS[selectDb]
|
||||
}
|
||||
|
||||
function connectionError(
|
||||
selectDb: number,
|
||||
timeout: NodeJS.Timeout,
|
||||
err: Error | string
|
||||
) {
|
||||
function connectionError(timeout: NodeJS.Timeout, err: Error | string) {
|
||||
// manually shut down, ignore errors
|
||||
if (CLOSED) {
|
||||
return
|
||||
}
|
||||
pickClient(selectDb).disconnect()
|
||||
CLOSED = true
|
||||
// always clear this on error
|
||||
clearTimeout(timeout)
|
||||
CONNECTED = false
|
||||
console.error("Redis connection failed - " + err)
|
||||
logAlert("Redis connection failed", err)
|
||||
setTimeout(() => {
|
||||
init()
|
||||
}, RETRY_PERIOD_MS)
|
||||
|
@ -79,11 +75,7 @@ function init(selectDb = DEFAULT_SELECT_DB) {
|
|||
// start the timer - only allowed 5 seconds to connect
|
||||
timeout = setTimeout(() => {
|
||||
if (!CONNECTED) {
|
||||
connectionError(
|
||||
selectDb,
|
||||
timeout,
|
||||
"Did not successfully connect in timeout"
|
||||
)
|
||||
connectionError(timeout, "Did not successfully connect in timeout")
|
||||
}
|
||||
}, STARTUP_TIMEOUT_MS)
|
||||
|
||||
|
@ -106,12 +98,13 @@ function init(selectDb = DEFAULT_SELECT_DB) {
|
|||
// allow the process to exit
|
||||
return
|
||||
}
|
||||
connectionError(selectDb, timeout, err)
|
||||
connectionError(timeout, err)
|
||||
})
|
||||
client.on("error", (err: Error) => {
|
||||
connectionError(selectDb, timeout, err)
|
||||
connectionError(timeout, err)
|
||||
})
|
||||
client.on("connect", () => {
|
||||
console.log(`Connected to Redis DB: ${selectDb}`)
|
||||
clearTimeout(timeout)
|
||||
CONNECTED = true
|
||||
})
|
||||
|
|
|
@ -2,7 +2,7 @@ import env from "../environment"
|
|||
import * as eventHelpers from "./events"
|
||||
import * as accountSdk from "../accounts"
|
||||
import * as cache from "../cache"
|
||||
import { doInTenant, getGlobalDB, getIdentity, getTenantId } from "../context"
|
||||
import { getGlobalDB, getIdentity, getTenantId } from "../context"
|
||||
import * as dbUtils from "../db"
|
||||
import { EmailUnavailableError, HTTPError } from "../errors"
|
||||
import * as platform from "../platform"
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
// Ensure the value is updated if the value prop changes outside the editor's
|
||||
// control
|
||||
$: checkValue(value)
|
||||
$: mde?.codemirror.on("change", debouncedUpdate)
|
||||
$: mde?.codemirror.on("blur", update)
|
||||
$: if (readonly || disabled) {
|
||||
mde?.togglePreview()
|
||||
}
|
||||
|
@ -30,21 +30,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
const debounce = (fn, interval) => {
|
||||
let timeout
|
||||
return () => {
|
||||
clearTimeout(timeout)
|
||||
timeout = setTimeout(fn, interval)
|
||||
}
|
||||
}
|
||||
|
||||
const update = () => {
|
||||
latestValue = mde.value()
|
||||
dispatch("change", latestValue)
|
||||
}
|
||||
|
||||
// Debounce the update function to avoid spamming it constantly
|
||||
const debouncedUpdate = debounce(update, 250)
|
||||
</script>
|
||||
|
||||
{#key height}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { string, number } from "yup"
|
||||
import { string, number, object } from "yup"
|
||||
|
||||
const propertyValidator = type => {
|
||||
if (type === "number") {
|
||||
|
@ -9,6 +9,10 @@ const propertyValidator = type => {
|
|||
return string().email().nullable()
|
||||
}
|
||||
|
||||
if (type === "object") {
|
||||
return object().nullable()
|
||||
}
|
||||
|
||||
return string().nullable()
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ build/
|
|||
docker-error.log
|
||||
envoy.yaml
|
||||
*.tar.gz
|
||||
prebuilds/
|
||||
dist/
|
||||
budibase-automation/
|
||||
budibase-component/
|
||||
|
|
|
@ -9,26 +9,11 @@
|
|||
"author": "Budibase",
|
||||
"license": "GPL-3.0",
|
||||
"scripts": {
|
||||
"prebuild": "rm -rf prebuilds 2> /dev/null && cp -r ../../node_modules/leveldown/prebuilds prebuilds",
|
||||
"rename": "renamer --find .node --replace .fake 'prebuilds/**'",
|
||||
"tsc": "node ../../scripts/build.js",
|
||||
"pkg": "pkg . --out-path build --no-bytecode --public --public-packages \"*\" -C GZip",
|
||||
"build": "yarn prebuild && yarn rename && yarn tsc && yarn pkg && yarn postbuild",
|
||||
"build": "yarn tsc",
|
||||
"check:types": "tsc -p tsconfig.json --noEmit --paths null",
|
||||
"postbuild": "rm -rf prebuilds 2> /dev/null",
|
||||
"start": "ts-node ./src/index.ts"
|
||||
},
|
||||
"pkg": {
|
||||
"targets": [
|
||||
"node18-linux",
|
||||
"node18-win",
|
||||
"node18-macos"
|
||||
],
|
||||
"assets": [
|
||||
"prebuilds/**/*"
|
||||
],
|
||||
"outputPath": "build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/backend-core": "0.0.0",
|
||||
"@budibase/string-templates": "0.0.0",
|
||||
|
@ -43,7 +28,6 @@
|
|||
"inquirer": "8.0.0",
|
||||
"lookpath": "1.1.0",
|
||||
"node-fetch": "2.6.7",
|
||||
"pkg": "5.8.0",
|
||||
"posthog-node": "1.3.0",
|
||||
"pouchdb": "7.3.0",
|
||||
"pouchdb-replication-stream": "1.2.9",
|
||||
|
@ -55,7 +39,6 @@
|
|||
"@types/jest": "29.5.5",
|
||||
"@types/node-fetch": "2.6.4",
|
||||
"@types/pouchdb": "^6.4.0",
|
||||
"renamer": "^4.0.0",
|
||||
"ts-node": "10.8.1",
|
||||
"typescript": "5.2.2"
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,10 +1,9 @@
|
|||
#!/usr/bin/env node
|
||||
process.env.DISABLE_PINO_LOGGER = "1"
|
||||
import "./prebuilds"
|
||||
import "./environment"
|
||||
import { getCommands } from "./options"
|
||||
import { Command } from "commander"
|
||||
import { getHelpDescription } from "./utils"
|
||||
import { getHelpDescription, error } from "./utils"
|
||||
import { version } from "../package.json"
|
||||
|
||||
// add hosting config
|
||||
|
@ -21,6 +20,23 @@ async function init() {
|
|||
await program.parseAsync(process.argv)
|
||||
}
|
||||
|
||||
const events = ["exit", "SIGINT", "SIGUSR1", "SIGUSR2", "uncaughtException"]
|
||||
events.forEach(event => {
|
||||
process.on(event, (evt?: number) => {
|
||||
if (evt && !isNaN(evt)) {
|
||||
return
|
||||
}
|
||||
if (evt) {
|
||||
console.error(
|
||||
error(
|
||||
"Failed to run CLI command - please report with the following message:"
|
||||
)
|
||||
)
|
||||
console.error(error(evt))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
init().catch(err => {
|
||||
console.error(`Unexpected error - `, err)
|
||||
})
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
import os from "os"
|
||||
import { join } from "path"
|
||||
import fs from "fs"
|
||||
import { error } from "./utils"
|
||||
|
||||
const PREBUILDS = "prebuilds"
|
||||
const ARCH = `${os.platform()}-${os.arch()}`
|
||||
const PREBUILD_DIR = join(process.execPath, "..", "cli", PREBUILDS, ARCH)
|
||||
|
||||
// running as built CLI pkg bundle
|
||||
if (!process.argv[0].includes("node")) {
|
||||
checkForBinaries()
|
||||
}
|
||||
|
||||
function localPrebuildPath() {
|
||||
return join(process.execPath, "..", PREBUILDS)
|
||||
}
|
||||
|
||||
function checkForBinaries() {
|
||||
const readDir = join(__filename, "..", "..", "..", "cli", PREBUILDS, ARCH)
|
||||
if (fs.existsSync(PREBUILD_DIR) || !fs.existsSync(readDir)) {
|
||||
return
|
||||
}
|
||||
const natives = fs.readdirSync(readDir)
|
||||
if (fs.existsSync(readDir)) {
|
||||
const writePath = join(localPrebuildPath(), ARCH)
|
||||
fs.mkdirSync(writePath, { recursive: true })
|
||||
for (let native of natives) {
|
||||
const filename = `${native.split(".fake")[0]}.node`
|
||||
fs.cpSync(join(readDir, native), join(writePath, filename))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function cleanup(evt?: number) {
|
||||
// cleanup prebuilds first
|
||||
const path = localPrebuildPath()
|
||||
if (fs.existsSync(path)) {
|
||||
fs.rmSync(path, { recursive: true })
|
||||
}
|
||||
if (evt && !isNaN(evt)) {
|
||||
return
|
||||
}
|
||||
if (evt) {
|
||||
console.error(
|
||||
error(
|
||||
"Failed to run CLI command - please report with the following message:"
|
||||
)
|
||||
)
|
||||
console.error(error(evt))
|
||||
}
|
||||
}
|
||||
|
||||
const events = ["exit", "SIGINT", "SIGUSR1", "SIGUSR2", "uncaughtException"]
|
||||
events.forEach(event => {
|
||||
process.on(event, cleanup)
|
||||
})
|
|
@ -0,0 +1,196 @@
|
|||
#!/bin/node
|
||||
const {
|
||||
createApp,
|
||||
getTable,
|
||||
createRow,
|
||||
createTable,
|
||||
getApp,
|
||||
getRows,
|
||||
} = require("./utils")
|
||||
|
||||
const Chance = require("chance")
|
||||
|
||||
const generator = new Chance()
|
||||
|
||||
const STUDENT_COUNT = 500
|
||||
const SUBJECT_COUNT = 10
|
||||
|
||||
let { apiKey, appId } = require("yargs")
|
||||
.demandOption(["apiKey"])
|
||||
.option("appId").argv
|
||||
|
||||
const start = Date.now()
|
||||
async function batchCreate(apiKey, appId, table, items, batchSize = 100) {
|
||||
let i = 0
|
||||
let errors = 0
|
||||
|
||||
async function createSingleRow(item) {
|
||||
try {
|
||||
const row = await createRow(apiKey, appId, table, item)
|
||||
console.log(
|
||||
`${table.name} - ${++i} of ${items.length} created (${
|
||||
(Date.now() - start) / 1000
|
||||
}s)`
|
||||
)
|
||||
return row
|
||||
} catch {
|
||||
errors++
|
||||
}
|
||||
}
|
||||
|
||||
const rows = []
|
||||
const maxConcurrency = Math.min(batchSize, items.length)
|
||||
const inFlight = {}
|
||||
|
||||
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
||||
const item = items[itemIndex]
|
||||
const promise = createSingleRow(item)
|
||||
.then(result => {
|
||||
rows.push(result)
|
||||
})
|
||||
.finally(() => {
|
||||
delete inFlight[itemIndex]
|
||||
})
|
||||
|
||||
inFlight[itemIndex] = promise
|
||||
|
||||
if (Object.keys(inFlight).length >= maxConcurrency) {
|
||||
await Promise.race(Object.values(inFlight))
|
||||
}
|
||||
}
|
||||
|
||||
await Promise.all(Object.values(inFlight))
|
||||
|
||||
if (errors) {
|
||||
console.error(
|
||||
`${table.name} - ${errors} creation errored (${
|
||||
(Date.now() - start) / 1000
|
||||
}s)`
|
||||
)
|
||||
}
|
||||
|
||||
return rows
|
||||
}
|
||||
|
||||
const useExistingApp = !!appId
|
||||
|
||||
async function upsertTable(appId, tableName, tableData) {
|
||||
if (useExistingApp) {
|
||||
return await getTable(apiKey, appId, tableName)
|
||||
}
|
||||
|
||||
const table = await createTable(apiKey, appId, {
|
||||
...tableData,
|
||||
name: tableName,
|
||||
})
|
||||
return table
|
||||
}
|
||||
|
||||
async function run() {
|
||||
if (!appId) {
|
||||
const app = appId ? await getApp(apiKey, appId) : await createApp(apiKey)
|
||||
appId = app._id
|
||||
|
||||
console.log(`App created. Url: http://localhost:10000/builder/app/${appId}`)
|
||||
} else {
|
||||
console.log(
|
||||
`App retrieved. Url: http://localhost:10000/builder/app/${appId}`
|
||||
)
|
||||
}
|
||||
|
||||
const studentsTable = await getTable(apiKey, appId, "Students")
|
||||
|
||||
let studentNumber = studentsTable.schema["Auto ID"].lastID
|
||||
const students = await batchCreate(
|
||||
apiKey,
|
||||
appId,
|
||||
studentsTable,
|
||||
Array.from({ length: STUDENT_COUNT }).map(() => ({
|
||||
"Student Number": (++studentNumber).toString(),
|
||||
"First Name": generator.first(),
|
||||
"Last Name": generator.last(),
|
||||
Gender: generator.pickone(["M", "F"]),
|
||||
Grade: generator.pickone(["8", "9", "10", "11"]),
|
||||
"Tardiness (Days)": generator.integer({ min: 1, max: 100 }),
|
||||
"Home Number": generator.phone(),
|
||||
"Attendance_(%)": generator.integer({ min: 0, max: 100 }),
|
||||
}))
|
||||
)
|
||||
|
||||
const subjectTable = await upsertTable(appId, "Subjects", {
|
||||
schema: {
|
||||
Name: {
|
||||
name: "Name",
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
primaryDisplay: "Name",
|
||||
})
|
||||
|
||||
const subjects = useExistingApp
|
||||
? await getRows(apiKey, appId, subjectTable._id)
|
||||
: await batchCreate(
|
||||
apiKey,
|
||||
appId,
|
||||
subjectTable,
|
||||
Array.from({ length: SUBJECT_COUNT }).map(() => ({
|
||||
Name: generator.profession(),
|
||||
}))
|
||||
)
|
||||
|
||||
const gradesTable = await upsertTable(appId, "Grades", {
|
||||
schema: {
|
||||
Score: {
|
||||
name: "Score",
|
||||
type: "number",
|
||||
},
|
||||
Student: {
|
||||
name: "Student",
|
||||
tableId: studentsTable._id,
|
||||
constraints: {
|
||||
presence: true,
|
||||
type: "array",
|
||||
},
|
||||
fieldName: "Grades",
|
||||
relationshipType: "one-to-many",
|
||||
type: "link",
|
||||
},
|
||||
Subject: {
|
||||
name: "Subject",
|
||||
tableId: subjectTable._id,
|
||||
constraints: {
|
||||
presence: true,
|
||||
type: "array",
|
||||
},
|
||||
fieldName: "Grades",
|
||||
relationshipType: "one-to-many",
|
||||
type: "link",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
await batchCreate(
|
||||
apiKey,
|
||||
appId,
|
||||
gradesTable,
|
||||
students.flatMap(student =>
|
||||
subjects.map(subject => ({
|
||||
Score: generator.integer({ min: 0, max: 100 }),
|
||||
Student: [student],
|
||||
Subject: [subject],
|
||||
}))
|
||||
)
|
||||
)
|
||||
|
||||
console.log(
|
||||
`Access the app here: http://localhost:10000/builder/app/${appId}`
|
||||
)
|
||||
}
|
||||
|
||||
run()
|
||||
.then(() => {
|
||||
console.log(`Done in ${(Date.now() - start) / 1000} seconds`)
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
})
|
|
@ -0,0 +1,29 @@
|
|||
#!/bin/node
|
||||
const { searchApps, deleteApp } = require("./utils")
|
||||
|
||||
if (!process.argv[2]) {
|
||||
console.error("Please specify an API key as script argument.")
|
||||
process.exit(-1)
|
||||
}
|
||||
|
||||
async function run() {
|
||||
const apiKey = process.argv[2]
|
||||
const apps = await searchApps(apiKey)
|
||||
console.log(`Deleting ${apps.length} apps`)
|
||||
|
||||
let deletedApps = 0
|
||||
await Promise.all(
|
||||
apps.map(async app => {
|
||||
await deleteApp(apiKey, app._id)
|
||||
console.log(`App ${++deletedApps} of ${apps.length} deleted`)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
run()
|
||||
.then(() => {
|
||||
console.log("Done!")
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
})
|
|
@ -2,7 +2,8 @@ const fetch = require("node-fetch")
|
|||
const uuid = require("uuid/v4")
|
||||
|
||||
const URL_APP = "http://localhost:10000/api/public/v1/applications"
|
||||
const URL_TABLE = "http://localhost:10000/api/public/v1/tables/search"
|
||||
const URL_TABLE = "http://localhost:10000/api/public/v1/tables"
|
||||
const URL_SEARCH_TABLE = "http://localhost:10000/api/public/v1/tables/search"
|
||||
|
||||
async function request(apiKey, url, method, body, appId = undefined) {
|
||||
const headers = {
|
||||
|
@ -37,30 +38,64 @@ exports.createApp = async apiKey => {
|
|||
return json.data
|
||||
}
|
||||
|
||||
exports.getTable = async (apiKey, appId) => {
|
||||
const res = await request(apiKey, URL_TABLE, "POST", {}, appId)
|
||||
exports.getApp = async (apiKey, appId) => {
|
||||
const res = await request(apiKey, `${URL_APP}/${appId}`, "GET")
|
||||
const json = await res.json()
|
||||
return json.data[0]
|
||||
return json.data
|
||||
}
|
||||
exports.searchApps = async apiKey => {
|
||||
const res = await request(apiKey, `${URL_APP}/search`, "POST", {})
|
||||
const json = await res.json()
|
||||
return json.data
|
||||
}
|
||||
|
||||
exports.createRow = async (apiKey, appId, table) => {
|
||||
const body = {}
|
||||
for (let [key, schema] of Object.entries(table.schema)) {
|
||||
let fake
|
||||
switch (schema.type) {
|
||||
default:
|
||||
case "string":
|
||||
fake = schema.constraints.inclusion
|
||||
? schema.constraints.inclusion[0]
|
||||
: "a"
|
||||
break
|
||||
case "number":
|
||||
fake = 1
|
||||
break
|
||||
exports.deleteApp = async (apiKey, appId) => {
|
||||
const res = await request(apiKey, `${URL_APP}/${appId}`, "DELETE")
|
||||
return res
|
||||
}
|
||||
|
||||
exports.getTable = async (apiKey, appId, tableName) => {
|
||||
const res = await request(apiKey, URL_SEARCH_TABLE, "POST", {}, appId)
|
||||
const json = await res.json()
|
||||
const table = json.data.find(t => t.name === tableName)
|
||||
if (!table) {
|
||||
throw `Table '${tableName} not found`
|
||||
}
|
||||
return table
|
||||
}
|
||||
|
||||
exports.createRow = async (apiKey, appId, table, body) => {
|
||||
if (!body) {
|
||||
body = {}
|
||||
for (let [key, schema] of Object.entries(table.schema)) {
|
||||
let fake
|
||||
switch (schema.type) {
|
||||
default:
|
||||
case "string":
|
||||
fake = schema.constraints?.inclusion
|
||||
? schema.constraints.inclusion[0]
|
||||
: "a"
|
||||
break
|
||||
case "number":
|
||||
fake = 1
|
||||
break
|
||||
}
|
||||
body[key] = fake
|
||||
}
|
||||
body[key] = fake
|
||||
}
|
||||
const url = `http://localhost:10000/api/public/v1/tables/${table._id}/rows`
|
||||
const res = await request(apiKey, url, "POST", body, appId)
|
||||
return (await res.json()).data
|
||||
}
|
||||
|
||||
exports.getRows = async (apiKey, appId, tableId) => {
|
||||
const url = `${URL_TABLE}/${tableId}/rows/search`
|
||||
const res = await request(apiKey, url, "POST", {}, appId)
|
||||
return (await res.json()).data
|
||||
}
|
||||
|
||||
exports.createTable = async (apiKey, appId, config) => {
|
||||
const res = await request(apiKey, URL_TABLE, "POST", config, appId)
|
||||
const json = await res.json()
|
||||
return json.data
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import {
|
|||
inputProcessing,
|
||||
outputProcessing,
|
||||
} from "../../../utilities/rowProcessor"
|
||||
import { cloneDeep, isEqual } from "lodash"
|
||||
import { cloneDeep } from "lodash"
|
||||
|
||||
export async function handleRequest<T extends Operation>(
|
||||
operation: T,
|
||||
|
@ -86,50 +86,6 @@ export async function patch(ctx: UserCtx<PatchRowRequest, PatchRowResponse>) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function save(ctx: UserCtx) {
|
||||
const inputs = ctx.request.body
|
||||
const tableId = utils.getTableId(ctx)
|
||||
|
||||
const table = await sdk.tables.getTable(tableId)
|
||||
const { table: updatedTable, row } = await inputProcessing(
|
||||
ctx.user?._id,
|
||||
cloneDeep(table),
|
||||
inputs
|
||||
)
|
||||
|
||||
const validateResult = await sdk.rows.utils.validate({
|
||||
row,
|
||||
tableId,
|
||||
})
|
||||
if (!validateResult.valid) {
|
||||
throw { validation: validateResult.errors }
|
||||
}
|
||||
|
||||
const response = await handleRequest(Operation.CREATE, tableId, {
|
||||
row,
|
||||
})
|
||||
|
||||
if (!isEqual(table, updatedTable)) {
|
||||
await sdk.tables.saveTable(updatedTable)
|
||||
}
|
||||
|
||||
const rowId = response.row._id
|
||||
if (rowId) {
|
||||
const row = await sdk.rows.external.getRow(tableId, rowId, {
|
||||
relationships: true,
|
||||
})
|
||||
return {
|
||||
...response,
|
||||
row: await outputProcessing(table, row, {
|
||||
preserveLinks: true,
|
||||
squash: true,
|
||||
}),
|
||||
}
|
||||
} else {
|
||||
return response
|
||||
}
|
||||
}
|
||||
|
||||
export async function find(ctx: UserCtx): Promise<Row> {
|
||||
const id = ctx.params.rowId
|
||||
const tableId = utils.getTableId(ctx)
|
||||
|
|
|
@ -30,7 +30,7 @@ import { Format } from "../view/exporters"
|
|||
|
||||
export * as views from "./views"
|
||||
|
||||
function pickApi(tableId: any) {
|
||||
function pickApi(tableId: string) {
|
||||
if (isExternalTableID(tableId)) {
|
||||
return external
|
||||
}
|
||||
|
@ -84,9 +84,12 @@ export const save = async (ctx: UserCtx<Row, Row>) => {
|
|||
return patch(ctx as UserCtx<PatchRowRequest, PatchRowResponse>)
|
||||
}
|
||||
const { row, table, squashed } = await quotas.addRow(() =>
|
||||
quotas.addQuery(() => pickApi(tableId).save(ctx), {
|
||||
datasourceId: tableId,
|
||||
})
|
||||
quotas.addQuery(
|
||||
() => sdk.rows.save(tableId, ctx.request.body, ctx.user?._id),
|
||||
{
|
||||
datasourceId: tableId,
|
||||
}
|
||||
)
|
||||
)
|
||||
ctx.status = 200
|
||||
ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:save`, appId, row, table)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as linkRows from "../../../db/linkedRows"
|
||||
import { generateRowID, InternalTables } from "../../../db/utils"
|
||||
import { InternalTables } from "../../../db/utils"
|
||||
import * as userController from "../user"
|
||||
import {
|
||||
AttachmentCleanup,
|
||||
|
@ -94,45 +94,6 @@ export async function patch(ctx: UserCtx<PatchRowRequest, PatchRowResponse>) {
|
|||
})
|
||||
}
|
||||
|
||||
export async function save(ctx: UserCtx) {
|
||||
let inputs = ctx.request.body
|
||||
inputs.tableId = utils.getTableId(ctx)
|
||||
|
||||
if (!inputs._rev && !inputs._id) {
|
||||
inputs._id = generateRowID(inputs.tableId)
|
||||
}
|
||||
|
||||
// this returns the table and row incase they have been updated
|
||||
const dbTable = await sdk.tables.getTable(inputs.tableId)
|
||||
|
||||
// need to copy the table so it can be differenced on way out
|
||||
const tableClone = cloneDeep(dbTable)
|
||||
|
||||
let { table, row } = await inputProcessing(ctx.user?._id, tableClone, inputs)
|
||||
|
||||
const validateResult = await sdk.rows.utils.validate({
|
||||
row,
|
||||
table,
|
||||
})
|
||||
|
||||
if (!validateResult.valid) {
|
||||
throw { validation: validateResult.errors }
|
||||
}
|
||||
|
||||
// make sure link rows are up-to-date
|
||||
row = (await linkRows.updateLinks({
|
||||
eventType: linkRows.EventType.ROW_SAVE,
|
||||
row,
|
||||
tableId: row.tableId,
|
||||
table,
|
||||
})) as Row
|
||||
|
||||
return finaliseRow(table, row, {
|
||||
oldTable: dbTable,
|
||||
updateFormula: true,
|
||||
})
|
||||
}
|
||||
|
||||
export async function find(ctx: UserCtx): Promise<Row> {
|
||||
const tableId = utils.getTableId(ctx),
|
||||
rowId = ctx.params.rowId
|
||||
|
|
|
@ -5,8 +5,8 @@ import {
|
|||
processFormulas,
|
||||
} from "../../../utilities/rowProcessor"
|
||||
import { FieldTypes, FormulaTypes } from "../../../constants"
|
||||
import { context } from "@budibase/backend-core"
|
||||
import { Table, Row } from "@budibase/types"
|
||||
import { context, locks } from "@budibase/backend-core"
|
||||
import { Table, Row, LockType, LockName } from "@budibase/types"
|
||||
import * as linkRows from "../../../db/linkedRows"
|
||||
import sdk from "../../../sdk"
|
||||
import isEqual from "lodash/isEqual"
|
||||
|
@ -149,12 +149,22 @@ export async function finaliseRow(
|
|||
await db.put(table)
|
||||
} catch (err: any) {
|
||||
if (err.status === 409) {
|
||||
const updatedTable = await sdk.tables.getTable(table._id!)
|
||||
let response = processAutoColumn(null, updatedTable, row, {
|
||||
reprocessing: true,
|
||||
})
|
||||
await db.put(response.table)
|
||||
row = response.row
|
||||
// Some conflicts with the autocolumns occurred, we need to refetch the table and recalculate
|
||||
await locks.doWithLock(
|
||||
{
|
||||
type: LockType.AUTO_EXTEND,
|
||||
name: LockName.PROCESS_AUTO_COLUMNS,
|
||||
resource: table._id,
|
||||
},
|
||||
async () => {
|
||||
const latestTable = await sdk.tables.getTable(table._id!)
|
||||
let response = processAutoColumn(null, latestTable, row, {
|
||||
reprocessing: true,
|
||||
})
|
||||
await db.put(response.table)
|
||||
row = response.row
|
||||
}
|
||||
)
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ const publicRouter = new Router({
|
|||
prefix: PREFIX,
|
||||
})
|
||||
|
||||
if (limiter) {
|
||||
if (limiter && !env.isDev()) {
|
||||
publicRouter.use(limiter)
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import {
|
|||
} from "@budibase/types"
|
||||
import sdk from "../sdk"
|
||||
import { automationsEnabled } from "../features"
|
||||
import tracer from "dd-trace"
|
||||
|
||||
const REBOOT_CRON = "@reboot"
|
||||
const WH_STEP_ID = definitions.WEBHOOK.stepId
|
||||
|
@ -39,27 +40,62 @@ function loggingArgs(job: AutomationJob) {
|
|||
}
|
||||
|
||||
export async function processEvent(job: AutomationJob) {
|
||||
const appId = job.data.event.appId!
|
||||
const automationId = job.data.automation._id!
|
||||
return tracer.trace(
|
||||
"processEvent",
|
||||
{ resource: "automation" },
|
||||
async span => {
|
||||
const appId = job.data.event.appId!
|
||||
const automationId = job.data.automation._id!
|
||||
|
||||
const task = async () => {
|
||||
try {
|
||||
// need to actually await these so that an error can be captured properly
|
||||
console.log("automation running", ...loggingArgs(job))
|
||||
|
||||
const runFn = () => Runner.run(job)
|
||||
const result = await quotas.addAutomation(runFn, {
|
||||
span?.addTags({
|
||||
appId,
|
||||
automationId,
|
||||
job: {
|
||||
id: job.id,
|
||||
name: job.name,
|
||||
attemptsMade: job.attemptsMade,
|
||||
opts: {
|
||||
attempts: job.opts.attempts,
|
||||
priority: job.opts.priority,
|
||||
delay: job.opts.delay,
|
||||
repeat: job.opts.repeat,
|
||||
backoff: job.opts.backoff,
|
||||
lifo: job.opts.lifo,
|
||||
timeout: job.opts.timeout,
|
||||
jobId: job.opts.jobId,
|
||||
removeOnComplete: job.opts.removeOnComplete,
|
||||
removeOnFail: job.opts.removeOnFail,
|
||||
stackTraceLimit: job.opts.stackTraceLimit,
|
||||
preventParsingData: job.opts.preventParsingData,
|
||||
},
|
||||
},
|
||||
})
|
||||
console.log("automation completed", ...loggingArgs(job))
|
||||
return result
|
||||
} catch (err) {
|
||||
console.error(`automation was unable to run`, err, ...loggingArgs(job))
|
||||
return { err }
|
||||
}
|
||||
}
|
||||
|
||||
return await context.doInAutomationContext({ appId, automationId, task })
|
||||
const task = async () => {
|
||||
try {
|
||||
// need to actually await these so that an error can be captured properly
|
||||
console.log("automation running", ...loggingArgs(job))
|
||||
|
||||
const runFn = () => Runner.run(job)
|
||||
const result = await quotas.addAutomation(runFn, {
|
||||
automationId,
|
||||
})
|
||||
console.log("automation completed", ...loggingArgs(job))
|
||||
return result
|
||||
} catch (err) {
|
||||
span?.addTags({ error: true })
|
||||
console.error(
|
||||
`automation was unable to run`,
|
||||
err,
|
||||
...loggingArgs(job)
|
||||
)
|
||||
return { err }
|
||||
}
|
||||
}
|
||||
|
||||
return await context.doInAutomationContext({ appId, automationId, task })
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
export async function updateTestHistory(
|
||||
|
|
|
@ -2,35 +2,44 @@ import vm from "vm"
|
|||
import env from "./environment"
|
||||
import { setJSRunner } from "@budibase/string-templates"
|
||||
import { context, timers } from "@budibase/backend-core"
|
||||
import tracer from "dd-trace"
|
||||
|
||||
type TrackerFn = <T>(f: () => T) => T
|
||||
|
||||
export function init() {
|
||||
setJSRunner((js: string, ctx: vm.Context) => {
|
||||
const perRequestLimit = env.JS_PER_REQUEST_TIME_LIMIT_MS
|
||||
let track: TrackerFn = f => f()
|
||||
if (perRequestLimit) {
|
||||
const bbCtx = context.getCurrentContext()
|
||||
if (bbCtx) {
|
||||
if (!bbCtx.jsExecutionTracker) {
|
||||
bbCtx.jsExecutionTracker =
|
||||
timers.ExecutionTimeTracker.withLimit(perRequestLimit)
|
||||
return tracer.trace("runJS", {}, span => {
|
||||
const perRequestLimit = env.JS_PER_REQUEST_TIME_LIMIT_MS
|
||||
let track: TrackerFn = f => f()
|
||||
if (perRequestLimit) {
|
||||
const bbCtx = context.getCurrentContext()
|
||||
if (bbCtx) {
|
||||
if (!bbCtx.jsExecutionTracker) {
|
||||
bbCtx.jsExecutionTracker =
|
||||
timers.ExecutionTimeTracker.withLimit(perRequestLimit)
|
||||
}
|
||||
track = bbCtx.jsExecutionTracker.track.bind(bbCtx.jsExecutionTracker)
|
||||
span?.addTags({
|
||||
js: {
|
||||
limitMS: bbCtx.jsExecutionTracker.limitMs,
|
||||
elapsedMS: bbCtx.jsExecutionTracker.elapsedMS,
|
||||
},
|
||||
})
|
||||
}
|
||||
track = bbCtx.jsExecutionTracker.track.bind(bbCtx.jsExecutionTracker)
|
||||
}
|
||||
}
|
||||
|
||||
ctx = {
|
||||
...ctx,
|
||||
alert: undefined,
|
||||
setInterval: undefined,
|
||||
setTimeout: undefined,
|
||||
}
|
||||
vm.createContext(ctx)
|
||||
return track(() =>
|
||||
vm.runInNewContext(js, ctx, {
|
||||
timeout: env.JS_PER_EXECUTION_TIME_LIMIT_MS,
|
||||
})
|
||||
)
|
||||
ctx = {
|
||||
...ctx,
|
||||
alert: undefined,
|
||||
setInterval: undefined,
|
||||
setTimeout: undefined,
|
||||
}
|
||||
vm.createContext(ctx)
|
||||
return track(() =>
|
||||
vm.runInNewContext(js, ctx, {
|
||||
timeout: env.JS_PER_EXECUTION_TIME_LIMIT_MS,
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import { getCachedSelf } from "../utilities/global"
|
|||
import env from "../environment"
|
||||
import { isWebhookEndpoint } from "./utils"
|
||||
import { UserCtx, ContextUser } from "@budibase/types"
|
||||
import tracer from "dd-trace"
|
||||
|
||||
export default async (ctx: UserCtx, next: any) => {
|
||||
// try to get the appID from the request
|
||||
|
@ -20,6 +21,11 @@ export default async (ctx: UserCtx, next: any) => {
|
|||
return next()
|
||||
}
|
||||
|
||||
if (requestAppId) {
|
||||
const span = tracer.scope().active()
|
||||
span?.setTag("appId", requestAppId)
|
||||
}
|
||||
|
||||
// deny access to application preview
|
||||
if (!env.isTest()) {
|
||||
if (
|
||||
|
@ -70,6 +76,14 @@ export default async (ctx: UserCtx, next: any) => {
|
|||
return next()
|
||||
}
|
||||
|
||||
if (ctx.user) {
|
||||
const span = tracer.scope().active()
|
||||
if (ctx.user._id) {
|
||||
span?.setTag("userId", ctx.user._id)
|
||||
}
|
||||
span?.setTag("tenantId", ctx.user.tenantId)
|
||||
}
|
||||
|
||||
const userId = ctx.user ? generateUserMetadataID(ctx.user._id!) : undefined
|
||||
|
||||
// if the user is not in the right tenant then make sure to wipe their cookie
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
import { IncludeRelationship, Operation } from "@budibase/types"
|
||||
import { IncludeRelationship, Operation, Row } from "@budibase/types"
|
||||
import { handleRequest } from "../../../api/controllers/row/external"
|
||||
import { breakRowIdField } from "../../../integrations/utils"
|
||||
import sdk from "../../../sdk"
|
||||
import {
|
||||
inputProcessing,
|
||||
outputProcessing,
|
||||
} from "../../../utilities/rowProcessor"
|
||||
import cloneDeep from "lodash/fp/cloneDeep"
|
||||
import isEqual from "lodash/fp/isEqual"
|
||||
|
||||
export async function getRow(
|
||||
tableId: string,
|
||||
|
@ -15,3 +22,48 @@ export async function getRow(
|
|||
})
|
||||
return response ? response[0] : response
|
||||
}
|
||||
|
||||
export async function save(
|
||||
tableId: string,
|
||||
inputs: Row,
|
||||
userId: string | undefined
|
||||
) {
|
||||
const table = await sdk.tables.getTable(tableId)
|
||||
const { table: updatedTable, row } = await inputProcessing(
|
||||
userId,
|
||||
cloneDeep(table),
|
||||
inputs
|
||||
)
|
||||
|
||||
const validateResult = await sdk.rows.utils.validate({
|
||||
row,
|
||||
tableId,
|
||||
})
|
||||
if (!validateResult.valid) {
|
||||
throw { validation: validateResult.errors }
|
||||
}
|
||||
|
||||
const response = await handleRequest(Operation.CREATE, tableId, {
|
||||
row,
|
||||
})
|
||||
|
||||
if (!isEqual(table, updatedTable)) {
|
||||
await sdk.tables.saveTable(updatedTable)
|
||||
}
|
||||
|
||||
const rowId = response.row._id
|
||||
if (rowId) {
|
||||
const row = await sdk.rows.external.getRow(tableId, rowId, {
|
||||
relationships: true,
|
||||
})
|
||||
return {
|
||||
...response,
|
||||
row: await outputProcessing(table, row, {
|
||||
preserveLinks: true,
|
||||
squash: true,
|
||||
}),
|
||||
}
|
||||
} else {
|
||||
return response
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
import { db } from "@budibase/backend-core"
|
||||
import { Row } from "@budibase/types"
|
||||
import sdk from "../../../sdk"
|
||||
import cloneDeep from "lodash/fp/cloneDeep"
|
||||
import { finaliseRow } from "../../../api/controllers/row/staticFormula"
|
||||
import { inputProcessing } from "../../../utilities/rowProcessor"
|
||||
import * as linkRows from "../../../db/linkedRows"
|
||||
|
||||
export async function save(
|
||||
tableId: string,
|
||||
inputs: Row,
|
||||
userId: string | undefined
|
||||
) {
|
||||
inputs.tableId = tableId
|
||||
|
||||
if (!inputs._rev && !inputs._id) {
|
||||
inputs._id = db.generateRowID(inputs.tableId)
|
||||
}
|
||||
|
||||
// this returns the table and row incase they have been updated
|
||||
const dbTable = await sdk.tables.getTable(inputs.tableId)
|
||||
|
||||
// need to copy the table so it can be differenced on way out
|
||||
const tableClone = cloneDeep(dbTable)
|
||||
|
||||
let { table, row } = await inputProcessing(userId, tableClone, inputs)
|
||||
|
||||
const validateResult = await sdk.rows.utils.validate({
|
||||
row,
|
||||
table,
|
||||
})
|
||||
|
||||
if (!validateResult.valid) {
|
||||
throw { validation: validateResult.errors }
|
||||
}
|
||||
|
||||
// make sure link rows are up-to-date
|
||||
row = (await linkRows.updateLinks({
|
||||
eventType: linkRows.EventType.ROW_SAVE,
|
||||
row,
|
||||
tableId: row.tableId,
|
||||
table,
|
||||
})) as Row
|
||||
|
||||
return finaliseRow(table, row, {
|
||||
oldTable: dbTable,
|
||||
updateFormula: true,
|
||||
})
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
import { db as dbCore, context } from "@budibase/backend-core"
|
||||
import { Database, Row } from "@budibase/types"
|
||||
import { getRowParams } from "../../../db/utils"
|
||||
import { isExternalTableID } from "../../../integrations/utils"
|
||||
import * as internal from "./internal"
|
||||
import * as external from "./external"
|
||||
|
||||
export async function getAllInternalRows(appId?: string) {
|
||||
let db: Database
|
||||
|
@ -16,3 +19,18 @@ export async function getAllInternalRows(appId?: string) {
|
|||
)
|
||||
return response.rows.map(row => row.doc) as Row[]
|
||||
}
|
||||
|
||||
function pickApi(tableId: any) {
|
||||
if (isExternalTableID(tableId)) {
|
||||
return external
|
||||
}
|
||||
return internal
|
||||
}
|
||||
|
||||
export async function save(
|
||||
tableId: string,
|
||||
row: Row,
|
||||
userId: string | undefined
|
||||
) {
|
||||
return pickApi(tableId).save(tableId, row, userId)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
import tk from "timekeeper"
|
||||
import * as internalSdk from "../internal"
|
||||
|
||||
import { generator } from "@budibase/backend-core/tests"
|
||||
import {
|
||||
INTERNAL_TABLE_SOURCE_ID,
|
||||
TableSourceType,
|
||||
FieldType,
|
||||
Table,
|
||||
AutoFieldSubTypes,
|
||||
} from "@budibase/types"
|
||||
|
||||
import TestConfiguration from "../../../../tests/utilities/TestConfiguration"
|
||||
import { cache } from "@budibase/backend-core"
|
||||
|
||||
tk.freeze(Date.now())
|
||||
|
||||
describe("sdk >> rows >> internal", () => {
|
||||
const config = new TestConfiguration()
|
||||
|
||||
beforeAll(async () => {
|
||||
await config.init()
|
||||
})
|
||||
|
||||
function makeRow() {
|
||||
return {
|
||||
name: generator.first(),
|
||||
surname: generator.last(),
|
||||
age: generator.age(),
|
||||
address: generator.address(),
|
||||
}
|
||||
}
|
||||
|
||||
describe("save", () => {
|
||||
const tableData: Table = {
|
||||
name: generator.word(),
|
||||
type: "table",
|
||||
sourceId: INTERNAL_TABLE_SOURCE_ID,
|
||||
sourceType: TableSourceType.INTERNAL,
|
||||
schema: {
|
||||
name: {
|
||||
name: "name",
|
||||
type: FieldType.STRING,
|
||||
constraints: {
|
||||
type: FieldType.STRING,
|
||||
},
|
||||
},
|
||||
surname: {
|
||||
name: "surname",
|
||||
type: FieldType.STRING,
|
||||
constraints: {
|
||||
type: FieldType.STRING,
|
||||
},
|
||||
},
|
||||
age: {
|
||||
name: "age",
|
||||
type: FieldType.NUMBER,
|
||||
constraints: {
|
||||
type: FieldType.NUMBER,
|
||||
},
|
||||
},
|
||||
address: {
|
||||
name: "address",
|
||||
type: FieldType.STRING,
|
||||
constraints: {
|
||||
type: FieldType.STRING,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it("save will persist the row properly", async () => {
|
||||
const table = await config.createTable(tableData)
|
||||
const row = makeRow()
|
||||
|
||||
await config.doInContext(config.appId, async () => {
|
||||
const response = await internalSdk.save(
|
||||
table._id!,
|
||||
row,
|
||||
config.user._id
|
||||
)
|
||||
|
||||
expect(response).toEqual({
|
||||
table,
|
||||
row: {
|
||||
...row,
|
||||
type: "row",
|
||||
_rev: expect.stringMatching("1-.*"),
|
||||
},
|
||||
squashed: {
|
||||
...row,
|
||||
type: "row",
|
||||
_rev: expect.stringMatching("1-.*"),
|
||||
},
|
||||
})
|
||||
|
||||
const persistedRow = await config.getRow(table._id!, response.row._id!)
|
||||
expect(persistedRow).toEqual({
|
||||
...row,
|
||||
type: "row",
|
||||
_rev: expect.stringMatching("1-.*"),
|
||||
createdAt: expect.any(String),
|
||||
updatedAt: expect.any(String),
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it("auto ids will update when creating new rows", async () => {
|
||||
const table = await config.createTable({
|
||||
...tableData,
|
||||
schema: {
|
||||
...tableData.schema,
|
||||
id: {
|
||||
name: "id",
|
||||
type: FieldType.AUTO,
|
||||
subtype: AutoFieldSubTypes.AUTO_ID,
|
||||
autocolumn: true,
|
||||
lastID: 0,
|
||||
},
|
||||
},
|
||||
})
|
||||
const row = makeRow()
|
||||
|
||||
await config.doInContext(config.appId, async () => {
|
||||
const response = await internalSdk.save(
|
||||
table._id!,
|
||||
row,
|
||||
config.user._id
|
||||
)
|
||||
|
||||
expect(response).toEqual({
|
||||
table: {
|
||||
...table,
|
||||
schema: {
|
||||
...table.schema,
|
||||
id: {
|
||||
...table.schema.id,
|
||||
lastID: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
row: {
|
||||
...row,
|
||||
id: 1,
|
||||
type: "row",
|
||||
_rev: expect.stringMatching("1-.*"),
|
||||
},
|
||||
squashed: {
|
||||
...row,
|
||||
id: 1,
|
||||
type: "row",
|
||||
_rev: expect.stringMatching("1-.*"),
|
||||
},
|
||||
})
|
||||
|
||||
const persistedRow = await config.getRow(table._id!, response.row._id!)
|
||||
expect(persistedRow).toEqual({
|
||||
...row,
|
||||
type: "row",
|
||||
id: 1,
|
||||
_rev: expect.stringMatching("1-.*"),
|
||||
createdAt: expect.any(String),
|
||||
updatedAt: expect.any(String),
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it("auto ids will update when creating new rows in parallel", async () => {
|
||||
function makeRows(count: number) {
|
||||
return Array.from({ length: count }, () => makeRow())
|
||||
}
|
||||
|
||||
const table = await config.createTable({
|
||||
...tableData,
|
||||
schema: {
|
||||
...tableData.schema,
|
||||
id: {
|
||||
name: "id",
|
||||
type: FieldType.AUTO,
|
||||
subtype: AutoFieldSubTypes.AUTO_ID,
|
||||
autocolumn: true,
|
||||
lastID: 0,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
await config.doInContext(config.appId, async () => {
|
||||
for (const row of makeRows(5)) {
|
||||
await internalSdk.save(table._id!, row, config.user._id)
|
||||
}
|
||||
await Promise.all(
|
||||
makeRows(10).map(row =>
|
||||
internalSdk.save(table._id!, row, config.user._id)
|
||||
)
|
||||
)
|
||||
for (const row of makeRows(5)) {
|
||||
await internalSdk.save(table._id!, row, config.user._id)
|
||||
}
|
||||
})
|
||||
|
||||
const persistedRows = await config.getRows(table._id!)
|
||||
expect(persistedRows).toHaveLength(20)
|
||||
expect(persistedRows).toEqual(
|
||||
expect.arrayContaining(
|
||||
Array.from({ length: 20 }).map((_, i) =>
|
||||
expect.objectContaining({ id: i + 1 })
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
const persistedTable = await config.getTable(table._id)
|
||||
expect((table as any).schema.id.lastID).toBe(0)
|
||||
expect(persistedTable.schema.id.lastID).toBe(20)
|
||||
})
|
||||
})
|
||||
})
|
|
@ -34,6 +34,7 @@ import { cloneDeep } from "lodash/fp"
|
|||
import { performance } from "perf_hooks"
|
||||
import * as sdkUtils from "../sdk/utils"
|
||||
import env from "../environment"
|
||||
import tracer from "dd-trace"
|
||||
|
||||
threadUtils.threadSetup()
|
||||
const FILTER_STEP_ID = actions.BUILTIN_ACTION_DEFINITIONS.FILTER.stepId
|
||||
|
@ -242,281 +243,347 @@ class Orchestrator {
|
|||
}
|
||||
|
||||
async execute(): Promise<any> {
|
||||
// this will retrieve from context created at start of thread
|
||||
this._context.env = await sdkUtils.getEnvironmentVariables()
|
||||
let automation = this._automation
|
||||
let stopped = false
|
||||
let loopStep: AutomationStep | undefined = undefined
|
||||
return tracer.trace(
|
||||
"Orchestrator.execute",
|
||||
{ resource: "automation" },
|
||||
async span => {
|
||||
span?.addTags({
|
||||
appId: this._appId,
|
||||
automationId: this._automation._id,
|
||||
})
|
||||
|
||||
let stepCount = 0
|
||||
let loopStepNumber: any = undefined
|
||||
let loopSteps: LoopStep[] | undefined = []
|
||||
let metadata
|
||||
let timeoutFlag = false
|
||||
let wasLoopStep = false
|
||||
let timeout = this._job.data.event.timeout
|
||||
// check if this is a recurring automation,
|
||||
if (isProdAppID(this._appId) && isRecurring(automation)) {
|
||||
metadata = await this.getMetadata()
|
||||
const shouldStop = await this.checkIfShouldStop(metadata)
|
||||
if (shouldStop) {
|
||||
return
|
||||
}
|
||||
}
|
||||
const start = performance.now()
|
||||
for (let step of automation.definition.steps) {
|
||||
let input: any,
|
||||
iterations = 1,
|
||||
iterationCount = 0
|
||||
// this will retrieve from context created at start of thread
|
||||
this._context.env = await sdkUtils.getEnvironmentVariables()
|
||||
let automation = this._automation
|
||||
let stopped = false
|
||||
let loopStep: AutomationStep | undefined = undefined
|
||||
|
||||
if (timeoutFlag) {
|
||||
break
|
||||
}
|
||||
|
||||
if (timeout) {
|
||||
setTimeout(() => {
|
||||
timeoutFlag = true
|
||||
}, timeout || 12000)
|
||||
}
|
||||
|
||||
stepCount++
|
||||
if (step.stepId === LOOP_STEP_ID) {
|
||||
loopStep = step
|
||||
loopStepNumber = stepCount
|
||||
continue
|
||||
}
|
||||
|
||||
if (loopStep) {
|
||||
input = await processObject(loopStep.inputs, this._context)
|
||||
iterations = getLoopIterations(loopStep as LoopStep)
|
||||
}
|
||||
for (let index = 0; index < iterations; index++) {
|
||||
let originalStepInput = cloneDeep(step.inputs)
|
||||
// Handle if the user has set a max iteration count or if it reaches the max limit set by us
|
||||
if (loopStep && input.binding) {
|
||||
let tempOutput = {
|
||||
items: loopSteps,
|
||||
iterations: iterationCount,
|
||||
}
|
||||
try {
|
||||
loopStep.inputs.binding = automationUtils.typecastForLooping(
|
||||
loopStep as LoopStep,
|
||||
loopStep.inputs as LoopInput
|
||||
)
|
||||
} catch (err) {
|
||||
this.updateContextAndOutput(loopStepNumber, step, tempOutput, {
|
||||
status: AutomationErrors.INCORRECT_TYPE,
|
||||
success: false,
|
||||
})
|
||||
loopSteps = undefined
|
||||
loopStep = undefined
|
||||
break
|
||||
}
|
||||
let item = []
|
||||
if (
|
||||
typeof loopStep.inputs.binding === "string" &&
|
||||
loopStep.inputs.option === "String"
|
||||
) {
|
||||
item = automationUtils.stringSplit(loopStep.inputs.binding)
|
||||
} else if (Array.isArray(loopStep.inputs.binding)) {
|
||||
item = loopStep.inputs.binding
|
||||
}
|
||||
this._context.steps[loopStepNumber] = {
|
||||
currentItem: item[index],
|
||||
}
|
||||
|
||||
// The "Loop" binding in the front end is "fake", so replace it here so the context can understand it
|
||||
// Pretty hacky because we need to account for the row object
|
||||
for (let [key, value] of Object.entries(originalStepInput)) {
|
||||
if (typeof value === "object") {
|
||||
for (let [innerKey, innerValue] of Object.entries(
|
||||
originalStepInput[key]
|
||||
)) {
|
||||
if (typeof innerValue === "string") {
|
||||
originalStepInput[key][innerKey] =
|
||||
automationUtils.substituteLoopStep(
|
||||
innerValue,
|
||||
`steps.${loopStepNumber}`
|
||||
)
|
||||
} else if (typeof value === "object") {
|
||||
for (let [innerObject, innerValue] of Object.entries(
|
||||
originalStepInput[key][innerKey]
|
||||
)) {
|
||||
originalStepInput[key][innerKey][innerObject] =
|
||||
automationUtils.substituteLoopStep(
|
||||
innerValue as string,
|
||||
`steps.${loopStepNumber}`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (typeof value === "string") {
|
||||
originalStepInput[key] = automationUtils.substituteLoopStep(
|
||||
value,
|
||||
`steps.${loopStepNumber}`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
index === env.AUTOMATION_MAX_ITERATIONS ||
|
||||
index === parseInt(loopStep.inputs.iterations)
|
||||
) {
|
||||
this.updateContextAndOutput(loopStepNumber, step, tempOutput, {
|
||||
status: AutomationErrors.MAX_ITERATIONS,
|
||||
success: true,
|
||||
})
|
||||
loopSteps = undefined
|
||||
loopStep = undefined
|
||||
break
|
||||
}
|
||||
|
||||
let isFailure = false
|
||||
const currentItem = this._context.steps[loopStepNumber]?.currentItem
|
||||
if (currentItem && typeof currentItem === "object") {
|
||||
isFailure = Object.keys(currentItem).some(value => {
|
||||
return currentItem[value] === loopStep?.inputs.failure
|
||||
})
|
||||
} else {
|
||||
isFailure = currentItem && currentItem === loopStep.inputs.failure
|
||||
}
|
||||
|
||||
if (isFailure) {
|
||||
this.updateContextAndOutput(loopStepNumber, step, tempOutput, {
|
||||
status: AutomationErrors.FAILURE_CONDITION,
|
||||
success: false,
|
||||
})
|
||||
loopSteps = undefined
|
||||
loopStep = undefined
|
||||
break
|
||||
let stepCount = 0
|
||||
let loopStepNumber: any = undefined
|
||||
let loopSteps: LoopStep[] | undefined = []
|
||||
let metadata
|
||||
let timeoutFlag = false
|
||||
let wasLoopStep = false
|
||||
let timeout = this._job.data.event.timeout
|
||||
// check if this is a recurring automation,
|
||||
if (isProdAppID(this._appId) && isRecurring(automation)) {
|
||||
span?.addTags({ recurring: true })
|
||||
metadata = await this.getMetadata()
|
||||
const shouldStop = await this.checkIfShouldStop(metadata)
|
||||
if (shouldStop) {
|
||||
span?.addTags({ shouldStop: true })
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// execution stopped, record state for that
|
||||
if (stopped) {
|
||||
this.updateExecutionOutput(step.id, step.stepId, {}, STOPPED_STATUS)
|
||||
continue
|
||||
}
|
||||
|
||||
// If it's a loop step, we need to manually add the bindings to the context
|
||||
let stepFn = await this.getStepFunctionality(step.stepId)
|
||||
let inputs = await processObject(originalStepInput, this._context)
|
||||
inputs = automationUtils.cleanInputValues(inputs, step.schema.inputs)
|
||||
|
||||
try {
|
||||
// appId is always passed
|
||||
const outputs = await stepFn({
|
||||
inputs: inputs,
|
||||
appId: this._appId,
|
||||
emitter: this._emitter,
|
||||
context: this._context,
|
||||
const start = performance.now()
|
||||
for (let step of automation.definition.steps) {
|
||||
const stepSpan = tracer.startSpan("Orchestrator.execute.step", {
|
||||
childOf: span,
|
||||
})
|
||||
stepSpan.addTags({
|
||||
resource: "automation",
|
||||
step: {
|
||||
stepId: step.stepId,
|
||||
id: step.id,
|
||||
name: step.name,
|
||||
type: step.type,
|
||||
title: step.stepTitle,
|
||||
internal: step.internal,
|
||||
deprecated: step.deprecated,
|
||||
},
|
||||
})
|
||||
|
||||
this._context.steps[stepCount] = outputs
|
||||
// if filter causes us to stop execution don't break the loop, set a var
|
||||
// so that we can finish iterating through the steps and record that it stopped
|
||||
if (step.stepId === FILTER_STEP_ID && !outputs.result) {
|
||||
stopped = true
|
||||
this.updateExecutionOutput(step.id, step.stepId, step.inputs, {
|
||||
...outputs,
|
||||
...STOPPED_STATUS,
|
||||
})
|
||||
continue
|
||||
}
|
||||
if (loopStep && loopSteps) {
|
||||
loopSteps.push(outputs)
|
||||
} else {
|
||||
this.updateExecutionOutput(
|
||||
step.id,
|
||||
step.stepId,
|
||||
step.inputs,
|
||||
outputs
|
||||
)
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`Automation error - ${step.stepId} - ${err}`)
|
||||
return err
|
||||
}
|
||||
let input: any,
|
||||
iterations = 1,
|
||||
iterationCount = 0
|
||||
|
||||
if (loopStep) {
|
||||
iterationCount++
|
||||
if (index === iterations - 1) {
|
||||
try {
|
||||
if (timeoutFlag) {
|
||||
span?.addTags({ timedOut: true })
|
||||
break
|
||||
}
|
||||
|
||||
if (timeout) {
|
||||
setTimeout(() => {
|
||||
timeoutFlag = true
|
||||
}, timeout || 12000)
|
||||
}
|
||||
|
||||
stepCount++
|
||||
if (step.stepId === LOOP_STEP_ID) {
|
||||
loopStep = step
|
||||
loopStepNumber = stepCount
|
||||
continue
|
||||
}
|
||||
|
||||
if (loopStep) {
|
||||
input = await processObject(loopStep.inputs, this._context)
|
||||
iterations = getLoopIterations(loopStep as LoopStep)
|
||||
stepSpan?.addTags({ step: { iterations } })
|
||||
}
|
||||
for (let index = 0; index < iterations; index++) {
|
||||
let originalStepInput = cloneDeep(step.inputs)
|
||||
// Handle if the user has set a max iteration count or if it reaches the max limit set by us
|
||||
if (loopStep && input.binding) {
|
||||
let tempOutput = {
|
||||
items: loopSteps,
|
||||
iterations: iterationCount,
|
||||
}
|
||||
try {
|
||||
loopStep.inputs.binding = automationUtils.typecastForLooping(
|
||||
loopStep as LoopStep,
|
||||
loopStep.inputs as LoopInput
|
||||
)
|
||||
} catch (err) {
|
||||
this.updateContextAndOutput(
|
||||
loopStepNumber,
|
||||
step,
|
||||
tempOutput,
|
||||
{
|
||||
status: AutomationErrors.INCORRECT_TYPE,
|
||||
success: false,
|
||||
}
|
||||
)
|
||||
loopSteps = undefined
|
||||
loopStep = undefined
|
||||
break
|
||||
}
|
||||
let item = []
|
||||
if (
|
||||
typeof loopStep.inputs.binding === "string" &&
|
||||
loopStep.inputs.option === "String"
|
||||
) {
|
||||
item = automationUtils.stringSplit(loopStep.inputs.binding)
|
||||
} else if (Array.isArray(loopStep.inputs.binding)) {
|
||||
item = loopStep.inputs.binding
|
||||
}
|
||||
this._context.steps[loopStepNumber] = {
|
||||
currentItem: item[index],
|
||||
}
|
||||
|
||||
// The "Loop" binding in the front end is "fake", so replace it here so the context can understand it
|
||||
// Pretty hacky because we need to account for the row object
|
||||
for (let [key, value] of Object.entries(originalStepInput)) {
|
||||
if (typeof value === "object") {
|
||||
for (let [innerKey, innerValue] of Object.entries(
|
||||
originalStepInput[key]
|
||||
)) {
|
||||
if (typeof innerValue === "string") {
|
||||
originalStepInput[key][innerKey] =
|
||||
automationUtils.substituteLoopStep(
|
||||
innerValue,
|
||||
`steps.${loopStepNumber}`
|
||||
)
|
||||
} else if (typeof value === "object") {
|
||||
for (let [innerObject, innerValue] of Object.entries(
|
||||
originalStepInput[key][innerKey]
|
||||
)) {
|
||||
originalStepInput[key][innerKey][innerObject] =
|
||||
automationUtils.substituteLoopStep(
|
||||
innerValue as string,
|
||||
`steps.${loopStepNumber}`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (typeof value === "string") {
|
||||
originalStepInput[key] =
|
||||
automationUtils.substituteLoopStep(
|
||||
value,
|
||||
`steps.${loopStepNumber}`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
index === env.AUTOMATION_MAX_ITERATIONS ||
|
||||
index === parseInt(loopStep.inputs.iterations)
|
||||
) {
|
||||
this.updateContextAndOutput(
|
||||
loopStepNumber,
|
||||
step,
|
||||
tempOutput,
|
||||
{
|
||||
status: AutomationErrors.MAX_ITERATIONS,
|
||||
success: true,
|
||||
}
|
||||
)
|
||||
loopSteps = undefined
|
||||
loopStep = undefined
|
||||
break
|
||||
}
|
||||
|
||||
let isFailure = false
|
||||
const currentItem =
|
||||
this._context.steps[loopStepNumber]?.currentItem
|
||||
if (currentItem && typeof currentItem === "object") {
|
||||
isFailure = Object.keys(currentItem).some(value => {
|
||||
return currentItem[value] === loopStep?.inputs.failure
|
||||
})
|
||||
} else {
|
||||
isFailure =
|
||||
currentItem && currentItem === loopStep.inputs.failure
|
||||
}
|
||||
|
||||
if (isFailure) {
|
||||
this.updateContextAndOutput(
|
||||
loopStepNumber,
|
||||
step,
|
||||
tempOutput,
|
||||
{
|
||||
status: AutomationErrors.FAILURE_CONDITION,
|
||||
success: false,
|
||||
}
|
||||
)
|
||||
loopSteps = undefined
|
||||
loopStep = undefined
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// execution stopped, record state for that
|
||||
if (stopped) {
|
||||
this.updateExecutionOutput(
|
||||
step.id,
|
||||
step.stepId,
|
||||
{},
|
||||
STOPPED_STATUS
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
// If it's a loop step, we need to manually add the bindings to the context
|
||||
let stepFn = await this.getStepFunctionality(step.stepId)
|
||||
let inputs = await processObject(originalStepInput, this._context)
|
||||
inputs = automationUtils.cleanInputValues(
|
||||
inputs,
|
||||
step.schema.inputs
|
||||
)
|
||||
|
||||
try {
|
||||
// appId is always passed
|
||||
const outputs = await stepFn({
|
||||
inputs: inputs,
|
||||
appId: this._appId,
|
||||
emitter: this._emitter,
|
||||
context: this._context,
|
||||
})
|
||||
|
||||
this._context.steps[stepCount] = outputs
|
||||
// if filter causes us to stop execution don't break the loop, set a var
|
||||
// so that we can finish iterating through the steps and record that it stopped
|
||||
if (step.stepId === FILTER_STEP_ID && !outputs.result) {
|
||||
stopped = true
|
||||
this.updateExecutionOutput(
|
||||
step.id,
|
||||
step.stepId,
|
||||
step.inputs,
|
||||
{
|
||||
...outputs,
|
||||
...STOPPED_STATUS,
|
||||
}
|
||||
)
|
||||
continue
|
||||
}
|
||||
if (loopStep && loopSteps) {
|
||||
loopSteps.push(outputs)
|
||||
} else {
|
||||
this.updateExecutionOutput(
|
||||
step.id,
|
||||
step.stepId,
|
||||
step.inputs,
|
||||
outputs
|
||||
)
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`Automation error - ${step.stepId} - ${err}`)
|
||||
return err
|
||||
}
|
||||
|
||||
if (loopStep) {
|
||||
iterationCount++
|
||||
if (index === iterations - 1) {
|
||||
loopStep = undefined
|
||||
this._context.steps.splice(loopStepNumber, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
stepSpan?.finish()
|
||||
}
|
||||
|
||||
if (loopStep && iterations === 0) {
|
||||
loopStep = undefined
|
||||
this.executionOutput.steps.splice(loopStepNumber + 1, 0, {
|
||||
id: step.id,
|
||||
stepId: step.stepId,
|
||||
outputs: {
|
||||
status: AutomationStepStatus.NO_ITERATIONS,
|
||||
success: true,
|
||||
},
|
||||
inputs: {},
|
||||
})
|
||||
|
||||
this._context.steps.splice(loopStepNumber, 1)
|
||||
break
|
||||
iterations = 1
|
||||
}
|
||||
|
||||
// Delete the step after the loop step as it's irrelevant, since information is included
|
||||
// in the loop step
|
||||
if (wasLoopStep && !loopStep) {
|
||||
this._context.steps.splice(loopStepNumber + 1, 1)
|
||||
wasLoopStep = false
|
||||
}
|
||||
if (loopSteps && loopSteps.length) {
|
||||
let tempOutput = {
|
||||
success: true,
|
||||
items: loopSteps,
|
||||
iterations: iterationCount,
|
||||
}
|
||||
this.executionOutput.steps.splice(loopStepNumber + 1, 0, {
|
||||
id: step.id,
|
||||
stepId: step.stepId,
|
||||
outputs: tempOutput,
|
||||
inputs: step.inputs,
|
||||
})
|
||||
this._context.steps[loopStepNumber] = tempOutput
|
||||
|
||||
wasLoopStep = true
|
||||
loopSteps = []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (loopStep && iterations === 0) {
|
||||
loopStep = undefined
|
||||
this.executionOutput.steps.splice(loopStepNumber + 1, 0, {
|
||||
id: step.id,
|
||||
stepId: step.stepId,
|
||||
outputs: {
|
||||
status: AutomationStepStatus.NO_ITERATIONS,
|
||||
success: true,
|
||||
},
|
||||
inputs: {},
|
||||
})
|
||||
const end = performance.now()
|
||||
const executionTime = end - start
|
||||
|
||||
this._context.steps.splice(loopStepNumber, 1)
|
||||
iterations = 1
|
||||
}
|
||||
console.info(
|
||||
`Automation ID: ${automation._id} Execution time: ${executionTime} milliseconds`,
|
||||
{
|
||||
_logKey: "automation",
|
||||
executionTime,
|
||||
}
|
||||
)
|
||||
|
||||
// Delete the step after the loop step as it's irrelevant, since information is included
|
||||
// in the loop step
|
||||
if (wasLoopStep && !loopStep) {
|
||||
this._context.steps.splice(loopStepNumber + 1, 1)
|
||||
wasLoopStep = false
|
||||
}
|
||||
if (loopSteps && loopSteps.length) {
|
||||
let tempOutput = {
|
||||
success: true,
|
||||
items: loopSteps,
|
||||
iterations: iterationCount,
|
||||
// store the logs for the automation run
|
||||
try {
|
||||
await storeLog(this._automation, this.executionOutput)
|
||||
} catch (e: any) {
|
||||
if (e.status === 413 && e.request?.data) {
|
||||
// if content is too large we shouldn't log it
|
||||
delete e.request.data
|
||||
e.request.data = { message: "removed due to large size" }
|
||||
}
|
||||
logging.logAlert("Error writing automation log", e)
|
||||
}
|
||||
this.executionOutput.steps.splice(loopStepNumber + 1, 0, {
|
||||
id: step.id,
|
||||
stepId: step.stepId,
|
||||
outputs: tempOutput,
|
||||
inputs: step.inputs,
|
||||
})
|
||||
this._context.steps[loopStepNumber] = tempOutput
|
||||
|
||||
wasLoopStep = true
|
||||
loopSteps = []
|
||||
}
|
||||
}
|
||||
|
||||
const end = performance.now()
|
||||
const executionTime = end - start
|
||||
|
||||
console.info(
|
||||
`Automation ID: ${automation._id} Execution time: ${executionTime} milliseconds`,
|
||||
{
|
||||
_logKey: "automation",
|
||||
executionTime,
|
||||
if (isProdAppID(this._appId) && isRecurring(automation) && metadata) {
|
||||
await this.updateMetadata(metadata)
|
||||
}
|
||||
return this.executionOutput
|
||||
}
|
||||
)
|
||||
|
||||
// store the logs for the automation run
|
||||
try {
|
||||
await storeLog(this._automation, this.executionOutput)
|
||||
} catch (e: any) {
|
||||
if (e.status === 413 && e.request?.data) {
|
||||
// if content is too large we shouldn't log it
|
||||
delete e.request.data
|
||||
e.request.data = { message: "removed due to large size" }
|
||||
}
|
||||
logging.logAlert("Error writing automation log", e)
|
||||
}
|
||||
if (isProdAppID(this._appId) && isRecurring(automation) && metadata) {
|
||||
await this.updateMetadata(metadata)
|
||||
}
|
||||
return this.executionOutput
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
Row,
|
||||
Table,
|
||||
} from "@budibase/types"
|
||||
import tracer from "dd-trace"
|
||||
|
||||
interface FormulaOpts {
|
||||
dynamic?: boolean
|
||||
|
@ -50,35 +51,42 @@ export function processFormulas<T extends Row | Row[]>(
|
|||
inputRows: T,
|
||||
{ dynamic, contextRows }: FormulaOpts = { dynamic: true }
|
||||
): T {
|
||||
const rows = Array.isArray(inputRows) ? inputRows : [inputRows]
|
||||
if (rows) {
|
||||
for (let [column, schema] of Object.entries(table.schema)) {
|
||||
if (schema.type !== FieldTypes.FORMULA) {
|
||||
continue
|
||||
}
|
||||
return tracer.trace("processFormulas", {}, span => {
|
||||
const numRows = Array.isArray(inputRows) ? inputRows.length : 1
|
||||
span?.addTags({ table_id: table._id, dynamic, numRows })
|
||||
const rows = Array.isArray(inputRows) ? inputRows : [inputRows]
|
||||
if (rows) {
|
||||
for (let [column, schema] of Object.entries(table.schema)) {
|
||||
if (schema.type !== FieldTypes.FORMULA) {
|
||||
continue
|
||||
}
|
||||
|
||||
const isStatic = schema.formulaType === FormulaTypes.STATIC
|
||||
const isStatic = schema.formulaType === FormulaTypes.STATIC
|
||||
|
||||
if (
|
||||
schema.formula == null ||
|
||||
(dynamic && isStatic) ||
|
||||
(!dynamic && !isStatic)
|
||||
) {
|
||||
continue
|
||||
}
|
||||
// iterate through rows and process formula
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
let row = rows[i]
|
||||
let context = contextRows ? contextRows[i] : row
|
||||
let formula = schema.formula
|
||||
rows[i] = {
|
||||
...row,
|
||||
[column]: processStringSync(formula, context),
|
||||
if (
|
||||
schema.formula == null ||
|
||||
(dynamic && isStatic) ||
|
||||
(!dynamic && !isStatic)
|
||||
) {
|
||||
continue
|
||||
}
|
||||
// iterate through rows and process formula
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
let row = rows[i]
|
||||
let context = contextRows ? contextRows[i] : row
|
||||
let formula = schema.formula
|
||||
rows[i] = {
|
||||
...row,
|
||||
[column]: tracer.trace("processStringSync", {}, span => {
|
||||
span?.addTags({ table_id: table._id, column, static: isStatic })
|
||||
return processStringSync(formula, context)
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Array.isArray(inputRows) ? rows : rows[0]
|
||||
return Array.isArray(inputRows) ? rows : rows[0]
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,19 +1,26 @@
|
|||
const externalHandlebars = require("./external")
|
||||
const helperList = require("@budibase/handlebars-helpers")
|
||||
|
||||
let helpers = undefined
|
||||
|
||||
module.exports.getHelperList = () => {
|
||||
if (helpers) {
|
||||
return helpers
|
||||
}
|
||||
|
||||
helpers = {}
|
||||
let constructed = []
|
||||
for (let collection of externalHandlebars.externalCollections) {
|
||||
constructed.push(helperList[collection]())
|
||||
}
|
||||
const fullMap = {}
|
||||
for (let collection of constructed) {
|
||||
for (let [key, func] of Object.entries(collection)) {
|
||||
fullMap[key] = func
|
||||
helpers[key] = func
|
||||
}
|
||||
}
|
||||
for (let key of Object.keys(externalHandlebars.addedHelpers)) {
|
||||
fullMap[key] = externalHandlebars.addedHelpers[key]
|
||||
helpers[key] = externalHandlebars.addedHelpers[key]
|
||||
}
|
||||
return fullMap
|
||||
Object.freeze(helpers)
|
||||
return helpers
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ export enum LockName {
|
|||
PERSIST_WRITETHROUGH = "persist_writethrough",
|
||||
QUOTA_USAGE_EVENT = "quota_usage_event",
|
||||
APP_MIGRATION = "app_migrations",
|
||||
PROCESS_AUTO_COLUMNS = "process_auto_columns",
|
||||
}
|
||||
|
||||
export type LockOptions = {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import tk from "timekeeper"
|
||||
import _ from "lodash"
|
||||
import { mocks, structures } from "@budibase/backend-core/tests"
|
||||
import { generator, mocks, structures } from "@budibase/backend-core/tests"
|
||||
import {
|
||||
ScimCreateUserRequest,
|
||||
ScimGroupResponse,
|
||||
|
@ -14,9 +14,14 @@ import { events } from "@budibase/backend-core"
|
|||
jest.retryTimes(2, { logErrorsBeforeRetry: true })
|
||||
jest.setTimeout(30000)
|
||||
|
||||
mocks.licenses.useScimIntegration()
|
||||
|
||||
describe("scim", () => {
|
||||
beforeAll(async () => {
|
||||
tk.freeze(mocks.date.MOCK_DATE)
|
||||
mocks.licenses.useScimIntegration()
|
||||
|
||||
await config.setSCIMConfig(true)
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
jest.resetAllMocks()
|
||||
tk.freeze(mocks.date.MOCK_DATE)
|
||||
|
@ -570,8 +575,15 @@ describe("scim", () => {
|
|||
beforeAll(async () => {
|
||||
groups = []
|
||||
|
||||
for (let i = 0; i < groupCount; i++) {
|
||||
const body = structures.scim.createGroupRequest()
|
||||
const groupNames = generator.unique(
|
||||
() => generator.word(),
|
||||
groupCount
|
||||
)
|
||||
|
||||
for (const groupName of groupNames) {
|
||||
const body = structures.scim.createGroupRequest({
|
||||
displayName: groupName,
|
||||
})
|
||||
groups.push(await config.api.scimGroupsAPI.post({ body }))
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,9 @@ export const resetUpdate = async (resetCode: string, password: string) => {
|
|||
user.password = password
|
||||
user = await userSdk.db.save(user)
|
||||
|
||||
await cache.passwordReset.invalidateCode(resetCode)
|
||||
await sessions.invalidateSessions(userId)
|
||||
|
||||
// remove password from the user before sending events
|
||||
delete user.password
|
||||
await events.user.passwordReset(user)
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
import { cache, context, sessions, utils } from "@budibase/backend-core"
|
||||
import { loginUser, resetUpdate } from "../auth"
|
||||
import { generator, structures } from "@budibase/backend-core/tests"
|
||||
import { TestConfiguration } from "../../../tests"
|
||||
|
||||
describe("auth", () => {
|
||||
const config = new TestConfiguration()
|
||||
|
||||
describe("resetUpdate", () => {
|
||||
it("providing a valid code will update the password", async () => {
|
||||
await context.doInTenant(structures.tenant.id(), async () => {
|
||||
const user = await config.createUser()
|
||||
const previousPassword = user.password
|
||||
|
||||
const code = await cache.passwordReset.createCode(user._id!, {})
|
||||
const newPassword = generator.hash()
|
||||
|
||||
await resetUpdate(code, newPassword)
|
||||
|
||||
const persistedUser = await config.getUser(user.email)
|
||||
expect(persistedUser.password).not.toBe(previousPassword)
|
||||
expect(
|
||||
await utils.compare(newPassword, persistedUser.password!)
|
||||
).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
it("wrong code will not allow to reset the password", async () => {
|
||||
await context.doInTenant(structures.tenant.id(), async () => {
|
||||
const code = generator.hash()
|
||||
const newPassword = generator.hash()
|
||||
|
||||
await expect(resetUpdate(code, newPassword)).rejects.toThrow(
|
||||
"Provided information is not valid, cannot reset password - please try again."
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it("the same code cannot be used twice", async () => {
|
||||
await context.doInTenant(structures.tenant.id(), async () => {
|
||||
const user = await config.createUser()
|
||||
|
||||
const code = await cache.passwordReset.createCode(user._id!, {})
|
||||
const newPassword = generator.hash()
|
||||
|
||||
await resetUpdate(code, newPassword)
|
||||
await expect(resetUpdate(code, newPassword)).rejects.toThrow(
|
||||
"Provided information is not valid, cannot reset password - please try again."
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it("updating the password will invalidate all the sessions", async () => {
|
||||
await context.doInTenant(structures.tenant.id(), async () => {
|
||||
const user = await config.createUser()
|
||||
|
||||
await loginUser(user)
|
||||
|
||||
expect(await sessions.getSessionsForUser(user._id!)).toHaveLength(1)
|
||||
|
||||
const code = await cache.passwordReset.createCode(user._id!, {})
|
||||
const newPassword = generator.hash()
|
||||
|
||||
await resetUpdate(code, newPassword)
|
||||
|
||||
expect(await sessions.getSessionsForUser(user._id!)).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -1,6 +1,5 @@
|
|||
import { structures, mocks } from "../../../tests"
|
||||
import { env, context } from "@budibase/backend-core"
|
||||
import * as users from "../users"
|
||||
import { db as userDb } from "../"
|
||||
import { CloudAccount } from "@budibase/types"
|
||||
|
||||
|
|
412
yarn.lock
412
yarn.lock
|
@ -872,15 +872,6 @@
|
|||
eslint-visitor-keys "^2.1.0"
|
||||
semver "^6.3.1"
|
||||
|
||||
"@babel/generator@7.18.2":
|
||||
version "7.18.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.2.tgz#33873d6f89b21efe2da63fe554460f3df1c5880d"
|
||||
integrity sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==
|
||||
dependencies:
|
||||
"@babel/types" "^7.18.2"
|
||||
"@jridgewell/gen-mapping" "^0.3.0"
|
||||
jsesc "^2.5.1"
|
||||
|
||||
"@babel/generator@^7.22.5", "@babel/generator@^7.23.6", "@babel/generator@^7.7.2":
|
||||
version "7.23.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e"
|
||||
|
@ -1072,7 +1063,7 @@
|
|||
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83"
|
||||
integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==
|
||||
|
||||
"@babel/helper-validator-identifier@^7.16.7", "@babel/helper-validator-identifier@^7.22.20", "@babel/helper-validator-identifier@^7.22.5":
|
||||
"@babel/helper-validator-identifier@^7.22.20", "@babel/helper-validator-identifier@^7.22.5":
|
||||
version "7.22.20"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0"
|
||||
integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==
|
||||
|
@ -1110,11 +1101,6 @@
|
|||
chalk "^2.4.2"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/parser@7.18.4":
|
||||
version "7.18.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.4.tgz#6774231779dd700e0af29f6ad8d479582d7ce5ef"
|
||||
integrity sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==
|
||||
|
||||
"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.15", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.22.5", "@babel/parser@^7.23.6":
|
||||
version "7.23.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.6.tgz#ba1c9e512bda72a47e285ae42aff9d2a635a9e3b"
|
||||
|
@ -2032,15 +2018,7 @@
|
|||
debug "^4.3.1"
|
||||
globals "^11.1.0"
|
||||
|
||||
"@babel/types@7.18.4":
|
||||
version "7.18.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.4.tgz#27eae9b9fd18e9dccc3f9d6ad051336f307be354"
|
||||
integrity sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.16.7"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.16.8", "@babel/types@^7.18.2", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.6", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.16.8", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.6", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
|
||||
version "7.23.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.6.tgz#be33fdb151e1f5a56877d704492c240fc71c7ccd"
|
||||
integrity sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==
|
||||
|
@ -5602,7 +5580,7 @@
|
|||
"@types/node" "*"
|
||||
form-data "^3.0.0"
|
||||
|
||||
"@types/node@*", "@types/node@>=10.0.0", "@types/node@>=12.12.47", "@types/node@>=13.13.4", "@types/node@>=13.7.0", "@types/node@>=8.1.0":
|
||||
"@types/node@*", "@types/node@>=10.0.0", "@types/node@>=12.12.47", "@types/node@>=13.13.4", "@types/node@>=13.7.0":
|
||||
version "20.10.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.5.tgz#47ad460b514096b7ed63a1dae26fad0914ed3ab2"
|
||||
integrity sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==
|
||||
|
@ -5629,6 +5607,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.37.tgz#0bfcd173e8e1e328337473a8317e37b3b14fd30d"
|
||||
integrity sha512-7GgtHCs/QZrBrDzgIJnQtuSvhFSwhyYSI2uafSwZoNt1iOGhEN5fwNrQMjtONyHm9+/LoA4453jH0CMYcr06Pg==
|
||||
|
||||
"@types/node@>=8.1.0":
|
||||
version "20.10.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.6.tgz#a3ec84c22965802bf763da55b2394424f22bfbb5"
|
||||
integrity sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==
|
||||
dependencies:
|
||||
undici-types "~5.26.4"
|
||||
|
||||
"@types/nodemailer@^6.4.4":
|
||||
version "6.4.14"
|
||||
resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.14.tgz#5c81a5e856db7f8ede80013e6dbad7c5fb2283e2"
|
||||
|
@ -6581,11 +6566,6 @@ ansi-escapes@^4.2.1:
|
|||
dependencies:
|
||||
type-fest "^0.21.3"
|
||||
|
||||
ansi-regex@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
|
||||
integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==
|
||||
|
||||
ansi-regex@^4.1.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed"
|
||||
|
@ -6688,11 +6668,6 @@ app-module-path@^2.2.0:
|
|||
resolved "https://registry.yarnpkg.com/app-module-path/-/app-module-path-2.2.0.tgz#641aa55dfb7d6a6f0a8141c4b9c0aa50b6c24dd5"
|
||||
integrity sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==
|
||||
|
||||
aproba@^1.0.3:
|
||||
version "1.2.0"
|
||||
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"
|
||||
|
@ -6732,14 +6707,6 @@ are-we-there-yet@^3.0.0:
|
|||
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"
|
||||
integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==
|
||||
dependencies:
|
||||
delegates "^1.0.0"
|
||||
readable-stream "^2.0.6"
|
||||
|
||||
arg@^4.1.0:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
|
||||
|
@ -6784,21 +6751,6 @@ arr-union@^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"
|
||||
integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==
|
||||
|
||||
array-back@^4.0.1, array-back@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e"
|
||||
integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==
|
||||
|
||||
array-back@^6.2.0, array-back@^6.2.2:
|
||||
version "6.2.2"
|
||||
resolved "https://registry.yarnpkg.com/array-back/-/array-back-6.2.2.tgz#f567d99e9af88a6d3d2f9dfcc21db6f9ba9fd157"
|
||||
integrity sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==
|
||||
|
||||
array-buffer-byte-length@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead"
|
||||
|
@ -8127,11 +8079,6 @@ co@^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==
|
||||
|
||||
codemirror-spell-checker@1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/codemirror-spell-checker/-/codemirror-spell-checker-1.1.2.tgz#1c660f9089483ccb5113b9ba9ca19c3f4993371e"
|
||||
|
@ -8240,26 +8187,6 @@ combos@^0.2.0:
|
|||
resolved "https://registry.yarnpkg.com/combos/-/combos-0.2.0.tgz#dc31c5a899b42293d55fe19c064d3e6e207ba4f7"
|
||||
integrity sha512-Z6YfvgiTCERWJTj3wQiXamFhssdvz1n4ok447rS330lw3uL72WAx8IvrLU7xiE71uyb5WF8JEP+BWB5KhOoGeg==
|
||||
|
||||
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"
|
||||
integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==
|
||||
dependencies:
|
||||
array-back "^3.1.0"
|
||||
find-replace "^3.0.0"
|
||||
lodash.camelcase "^4.3.0"
|
||||
typical "^4.0.0"
|
||||
|
||||
command-line-usage@^6.1.1:
|
||||
version "6.1.3"
|
||||
resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.3.tgz#428fa5acde6a838779dfa30e44686f4b6761d957"
|
||||
integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==
|
||||
dependencies:
|
||||
array-back "^4.0.2"
|
||||
chalk "^2.4.2"
|
||||
table-layout "^1.0.2"
|
||||
typical "^5.2.0"
|
||||
|
||||
commander@6.2.0:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.0.tgz#b990bfb8ac030aedc6d11bc04d1488ffef56db75"
|
||||
|
@ -8408,7 +8335,7 @@ configstore@^5.0.1:
|
|||
write-file-atomic "^3.0.0"
|
||||
xdg-basedir "^4.0.0"
|
||||
|
||||
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==
|
||||
|
@ -8870,11 +8797,6 @@ curlconverter@3.21.0:
|
|||
string.prototype.startswith "^1.0.0"
|
||||
yamljs "^0.3.0"
|
||||
|
||||
current-module-paths@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/current-module-paths/-/current-module-paths-1.1.0.tgz#5d5bf214281d80aea264e642f028e672098238f6"
|
||||
integrity sha512-HGhLUszcgprjKmzvQoCQda8iEWsQn3sWVzPdttyJVR5cjfVDYcoyozQA5D1YXgab9v84SPMpSuD+YrPX6i1IMQ==
|
||||
|
||||
cwd@^0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/cwd/-/cwd-0.10.0.tgz#172400694057c22a13b0cf16162c7e4b7a7fe567"
|
||||
|
@ -9010,13 +8932,6 @@ decode-uri-component@^0.2.0, decode-uri-component@^0.2.2:
|
|||
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9"
|
||||
integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==
|
||||
|
||||
decompress-response@^4.2.0:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986"
|
||||
integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==
|
||||
dependencies:
|
||||
mimic-response "^2.0.0"
|
||||
|
||||
decompress-response@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
|
||||
|
@ -9122,7 +9037,7 @@ deep-equal@~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:
|
||||
deep-extend@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
|
||||
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
|
||||
|
@ -9151,10 +9066,10 @@ defaults@^1.0.3:
|
|||
dependencies:
|
||||
clone "^1.0.2"
|
||||
|
||||
defer-to-connect@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587"
|
||||
integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==
|
||||
defer-to-connect@^1.0.1:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591"
|
||||
integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==
|
||||
|
||||
deferred-leveldown@~0.2.0:
|
||||
version "0.2.0"
|
||||
|
@ -9295,11 +9210,6 @@ detect-indent@^5.0.0:
|
|||
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
|
||||
integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==
|
||||
|
||||
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"
|
||||
|
@ -10669,11 +10579,6 @@ fast-deep-equal@3.1.3, fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
|||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||
|
||||
fast-diff@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03"
|
||||
integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==
|
||||
|
||||
fast-glob@3.2.7:
|
||||
version "3.2.7"
|
||||
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1"
|
||||
|
@ -10825,14 +10730,6 @@ file-entry-cache@^6.0.1:
|
|||
dependencies:
|
||||
flat-cache "^3.0.4"
|
||||
|
||||
file-set@^5.1.2:
|
||||
version "5.1.3"
|
||||
resolved "https://registry.yarnpkg.com/file-set/-/file-set-5.1.3.tgz#44dde6a8ae52d69813ee22beccd7cfe28bc655d2"
|
||||
integrity sha512-mQ6dqz+z59on3B50IGF3ujNGbZmY1TAeLHpNfhLEeNM6Lky31w3RUlbCyqZWQs0DuZJQU4R2qDuVd9ojyzadcg==
|
||||
dependencies:
|
||||
array-back "^6.2.2"
|
||||
glob "^7.2.0"
|
||||
|
||||
file-type@17.1.3, file-type@^11.1.0, file-type@^12.1.0, file-type@^16.5.4, file-type@^3.8.0, file-type@^4.2.0, file-type@^5.2.0, file-type@^6.1.0:
|
||||
version "17.1.3"
|
||||
resolved "https://registry.yarnpkg.com/file-type/-/file-type-17.1.3.tgz#aa012d7e920f8fdec86cea34d7e59b3afb3d83b7"
|
||||
|
@ -10924,13 +10821,6 @@ find-pkg@^0.1.2:
|
|||
dependencies:
|
||||
find-file-up "^0.1.2"
|
||||
|
||||
find-replace@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38"
|
||||
integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==
|
||||
dependencies:
|
||||
array-back "^3.0.1"
|
||||
|
||||
find-up@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
|
||||
|
@ -11107,14 +10997,6 @@ fresh@^0.5.2, fresh@~0.5.2:
|
|||
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
|
||||
integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
|
||||
|
||||
from2@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
|
||||
integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==
|
||||
dependencies:
|
||||
inherits "^2.0.1"
|
||||
readable-stream "^2.0.0"
|
||||
|
||||
fs-constants@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
|
||||
|
@ -11238,20 +11120,6 @@ gauge@^4.0.3:
|
|||
strip-ansi "^6.0.1"
|
||||
wide-align "^1.1.5"
|
||||
|
||||
gauge@~2.7.3:
|
||||
version "2.7.4"
|
||||
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
|
||||
integrity sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==
|
||||
dependencies:
|
||||
aproba "^1.0.3"
|
||||
console-control-strings "^1.0.0"
|
||||
has-unicode "^2.0.0"
|
||||
object-assign "^4.1.0"
|
||||
signal-exit "^3.0.0"
|
||||
string-width "^1.0.1"
|
||||
strip-ansi "^3.0.1"
|
||||
wide-align "^1.1.0"
|
||||
|
||||
gaxios@^4.0.0:
|
||||
version "4.3.3"
|
||||
resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-4.3.3.tgz#d44bdefe52d34b6435cc41214fdb160b64abfc22"
|
||||
|
@ -11934,7 +11802,7 @@ has-tostringtag@^1.0.0:
|
|||
dependencies:
|
||||
has-symbols "^1.0.2"
|
||||
|
||||
has-unicode@2.0.1, has-unicode@^2.0.0, has-unicode@^2.0.1:
|
||||
has-unicode@2.0.1, has-unicode@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
|
||||
integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==
|
||||
|
@ -12490,14 +12358,6 @@ interpret@^2.2.0:
|
|||
resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9"
|
||||
integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
|
||||
|
||||
into-stream@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-6.0.0.tgz#4bfc1244c0128224e18b8870e85b2de8e66c6702"
|
||||
integrity sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==
|
||||
dependencies:
|
||||
from2 "^2.3.0"
|
||||
p-is-promise "^3.0.0"
|
||||
|
||||
invert-kv@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
|
||||
|
@ -12648,13 +12508,6 @@ is-class-hotfix@~0.0.6:
|
|||
resolved "https://registry.yarnpkg.com/is-class-hotfix/-/is-class-hotfix-0.0.6.tgz#a527d31fb23279281dde5f385c77b5de70a72435"
|
||||
integrity sha512-0n+pzCC6ICtVr/WXnN2f03TK/3BfXY7me4cjCAqT8TYXEl0+JBRoqBo94JJHXcyDSLUeWbNX8Fvy5g5RJdAstQ==
|
||||
|
||||
is-core-module@2.9.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69"
|
||||
integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==
|
||||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
is-core-module@^2.13.0, is-core-module@^2.13.1, is-core-module@^2.5.0, is-core-module@^2.8.1:
|
||||
version "2.13.1"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384"
|
||||
|
@ -12723,13 +12576,6 @@ is-extglob@^2.1.1:
|
|||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
|
||||
|
||||
is-fullwidth-code-point@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
|
||||
integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==
|
||||
dependencies:
|
||||
number-is-nan "^1.0.0"
|
||||
|
||||
is-fullwidth-code-point@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
|
||||
|
@ -14694,13 +14540,6 @@ load-json-file@^4.0.0:
|
|||
pify "^3.0.0"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
load-module@^4.2.1:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/load-module/-/load-module-4.2.1.tgz#3b596a4ddee52c59106d38160aa631a0ded68867"
|
||||
integrity sha512-Sbfg6R4LjvyThJpqUoADHMjyoI2+cL4msbCQeZ9kkY/CqP/TT2938eftKm7x4I2gd4/A+DEe6nePkbfWYbXwSw==
|
||||
dependencies:
|
||||
array-back "^6.2.0"
|
||||
|
||||
loader-runner@^4.2.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1"
|
||||
|
@ -14949,6 +14788,11 @@ loupe@^2.3.6:
|
|||
dependencies:
|
||||
get-func-name "^2.0.0"
|
||||
|
||||
lowercase-keys@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
|
||||
integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
|
||||
|
||||
lowercase-keys@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2"
|
||||
|
@ -15390,11 +15234,6 @@ mimic-fn@^2.0.0, mimic-fn@^2.1.0:
|
|||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
|
||||
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
|
||||
|
||||
mimic-response@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43"
|
||||
integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==
|
||||
|
||||
mimic-response@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
|
||||
|
@ -15749,14 +15588,6 @@ multimatch@5.0.0:
|
|||
arrify "^2.0.1"
|
||||
minimatch "^3.0.4"
|
||||
|
||||
multistream@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/multistream/-/multistream-4.1.0.tgz#7bf00dfd119556fbc153cff3de4c6d477909f5a8"
|
||||
integrity sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw==
|
||||
dependencies:
|
||||
once "^1.4.0"
|
||||
readable-stream "^3.6.0"
|
||||
|
||||
mute-stream@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
|
||||
|
@ -15889,13 +15720,6 @@ nice-try@^1.0.4:
|
|||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||
|
||||
node-abi@^2.21.0:
|
||||
version "2.30.1"
|
||||
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.30.1.tgz#c437d4b1fe0e285aaf290d45b45d4d7afedac4cf"
|
||||
integrity sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==
|
||||
dependencies:
|
||||
semver "^5.4.1"
|
||||
|
||||
node-abi@^3.3.0:
|
||||
version "3.52.0"
|
||||
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.52.0.tgz#ffba0a85f54e552547e5849015f40f9514d5ba7c"
|
||||
|
@ -15923,7 +15747,7 @@ node-duration@^1.0.4:
|
|||
resolved "https://registry.yarnpkg.com/node-duration/-/node-duration-1.0.4.tgz#3e94ecc0e473691c89c4560074503362071cecac"
|
||||
integrity sha512-eUXYNSY7DL53vqfTosggWkvyIW3bhAcqBDIlolgNYlZhianXTrCL50rlUJWD1eRqkIxMppXTfiFbp+9SjpPrgA==
|
||||
|
||||
node-fetch@2.6.0, node-fetch@2.6.7, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.6, node-fetch@^2.6.7, node-fetch@^2.6.9:
|
||||
node-fetch@2.6.0, node-fetch@2.6.7, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7, node-fetch@^2.6.9:
|
||||
version "2.6.7"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
|
||||
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
|
||||
|
@ -16236,16 +16060,6 @@ npm-run-path@^4.0.1:
|
|||
dependencies:
|
||||
path-key "^3.0.0"
|
||||
|
||||
npmlog@^4.0.1:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
|
||||
integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
|
||||
dependencies:
|
||||
are-we-there-yet "~1.1.2"
|
||||
console-control-strings "~1.1.0"
|
||||
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"
|
||||
|
@ -16273,11 +16087,6 @@ nth-check@^2.0.1:
|
|||
dependencies:
|
||||
boolbase "^1.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==
|
||||
|
||||
nunjucks@^3.2.3:
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/nunjucks/-/nunjucks-3.2.4.tgz#f0878eef528ce7b0aa35d67cc6898635fd74649e"
|
||||
|
@ -16379,7 +16188,7 @@ object-assign@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-2.1.1.tgz#43c36e5d569ff8e4816c4efa8be02d26967c18aa"
|
||||
integrity sha512-CdsOUYIh5wIiozhJ3rLQgmUTgcyzFwZZrqhkKhODMoGtPKM+wt0h0CNIoauJWMsS9822EdzPsF/6mb4nLvPN5g==
|
||||
|
||||
object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
|
||||
|
@ -16739,11 +16548,6 @@ p-is-promise@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e"
|
||||
integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==
|
||||
|
||||
p-is-promise@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-3.0.0.tgz#58e78c7dfe2e163cf2a04ff869e7c1dba64a5971"
|
||||
integrity sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==
|
||||
|
||||
p-limit@^1.1.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8"
|
||||
|
@ -17450,20 +17254,6 @@ pkg-dir@^4.2.0:
|
|||
dependencies:
|
||||
find-up "^4.0.0"
|
||||
|
||||
pkg-fetch@3.4.2:
|
||||
version "3.4.2"
|
||||
resolved "https://registry.yarnpkg.com/pkg-fetch/-/pkg-fetch-3.4.2.tgz#6f68ebc54842b73f8c0808959a9df3739dcb28b7"
|
||||
integrity sha512-0+uijmzYcnhC0hStDjm/cl2VYdrmVVBpe7Q8k9YBojxmR5tG8mvR9/nooQq3QSXiQqORDVOTY3XqMEqJVIzkHA==
|
||||
dependencies:
|
||||
chalk "^4.1.2"
|
||||
fs-extra "^9.1.0"
|
||||
https-proxy-agent "^5.0.0"
|
||||
node-fetch "^2.6.6"
|
||||
progress "^2.0.3"
|
||||
semver "^7.3.5"
|
||||
tar-fs "^2.1.1"
|
||||
yargs "^16.2.0"
|
||||
|
||||
pkg-types@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.0.3.tgz#988b42ab19254c01614d13f4f65a2cfc7880f868"
|
||||
|
@ -17473,26 +17263,6 @@ pkg-types@^1.0.3:
|
|||
mlly "^1.2.0"
|
||||
pathe "^1.1.0"
|
||||
|
||||
pkg@5.8.0:
|
||||
version "5.8.0"
|
||||
resolved "https://registry.yarnpkg.com/pkg/-/pkg-5.8.0.tgz#a77644aeff0b94a1656d7f76558837f7c754a4c0"
|
||||
integrity sha512-8h9PUDYFi+LOMLbIyGRdP21g08mAtHidSpofSrf8LWhxUWGHymaRzcopEGiynB5EhQmZUKM6PQ9kCImV2TpdjQ==
|
||||
dependencies:
|
||||
"@babel/generator" "7.18.2"
|
||||
"@babel/parser" "7.18.4"
|
||||
"@babel/types" "7.18.4"
|
||||
chalk "^4.1.2"
|
||||
fs-extra "^9.1.0"
|
||||
globby "^11.1.0"
|
||||
into-stream "^6.0.0"
|
||||
is-core-module "2.9.0"
|
||||
minimist "^1.2.6"
|
||||
multistream "^4.1.0"
|
||||
pkg-fetch "3.4.2"
|
||||
prebuild-install "6.1.4"
|
||||
resolve "^1.22.0"
|
||||
stream-meter "^1.0.4"
|
||||
|
||||
pkginfo@0.4.x:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.1.tgz#b5418ef0439de5425fc4995042dced14fb2a84ff"
|
||||
|
@ -18076,25 +17846,6 @@ pouchdb@7.3.0:
|
|||
uuid "8.3.2"
|
||||
vuvuzela "1.0.3"
|
||||
|
||||
prebuild-install@6.1.4:
|
||||
version "6.1.4"
|
||||
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.1.4.tgz#ae3c0142ad611d58570b89af4986088a4937e00f"
|
||||
integrity sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==
|
||||
dependencies:
|
||||
detect-libc "^1.0.3"
|
||||
expand-template "^2.0.3"
|
||||
github-from-package "0.0.0"
|
||||
minimist "^1.2.3"
|
||||
mkdirp-classic "^0.5.3"
|
||||
napi-build-utils "^1.0.1"
|
||||
node-abi "^2.21.0"
|
||||
npmlog "^4.0.1"
|
||||
pump "^3.0.0"
|
||||
rc "^1.2.7"
|
||||
simple-get "^3.0.3"
|
||||
tar-fs "^2.0.0"
|
||||
tunnel-agent "^0.6.0"
|
||||
|
||||
prebuild-install@^7.1.1:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45"
|
||||
|
@ -18219,11 +17970,6 @@ pretty@^2.0.0:
|
|||
extend-shallow "^2.0.1"
|
||||
js-beautify "^1.6.12"
|
||||
|
||||
printj@^1.3.0:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/printj/-/printj-1.3.1.tgz#9af6b1d55647a1587ac44f4c1654a4b95b8e12cb"
|
||||
integrity sha512-GA3TdL8szPK4AQ2YnOe/b+Y1jUFwmmGMMK/qbY7VcE3Z7FU8JstbKiKRzO6CIiAKPhTO8m01NoQ0V5f3jc4OGg==
|
||||
|
||||
prismjs@^1.25.0:
|
||||
version "1.29.0"
|
||||
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12"
|
||||
|
@ -18264,11 +18010,6 @@ process@^0.11.10:
|
|||
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
|
||||
integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
|
||||
|
||||
progress@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
|
||||
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
|
||||
|
||||
promise-inflight@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
|
||||
|
@ -18677,7 +18418,7 @@ readable-stream@1.1.14, readable-stream@^1.0.26-4, readable-stream@^1.0.27-1:
|
|||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
readable-stream@^2.0.0, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5, readable-stream@~2.3.6:
|
||||
readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5, readable-stream@~2.3.6:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b"
|
||||
integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
|
||||
|
@ -18819,11 +18560,6 @@ redlock@4.2.0:
|
|||
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"
|
||||
integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==
|
||||
|
||||
regenerate-unicode-properties@^10.1.0:
|
||||
version "10.1.0"
|
||||
resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c"
|
||||
|
@ -18930,24 +18666,6 @@ remove-trailing-slash@^0.1.1:
|
|||
resolved "https://registry.yarnpkg.com/remove-trailing-slash/-/remove-trailing-slash-0.1.1.tgz#be2285a59f39c74d1bce4f825950061915e3780d"
|
||||
integrity sha512-o4S4Qh6L2jpnCy83ysZDau+VORNvnFw07CKSAymkd6ICNVEPisMyzlc00KlvvicsxKck94SEwhDnMNdICzO+tA==
|
||||
|
||||
renamer@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/renamer/-/renamer-4.0.0.tgz#12e96979f2fec0f0ce31fa1c6384d668bc80f648"
|
||||
integrity sha512-yurufcXxbJfFBVAUoByNyDVH811zTZ/MrKo6gUH8pHGeAmdK7J5egj2lSNe57HuVIvnVzSalzeVGu8pi8UHGxg==
|
||||
dependencies:
|
||||
array-back "^6.2.0"
|
||||
chalk "^4.1.2"
|
||||
command-line-args "^5.2.0"
|
||||
command-line-usage "^6.1.1"
|
||||
current-module-paths "^1.1.0"
|
||||
fast-diff "^1.2.0"
|
||||
file-set "^5.1.2"
|
||||
global-dirs "^3.0.0"
|
||||
load-module "^4.2.1"
|
||||
printj "^1.3.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"
|
||||
|
@ -19077,7 +18795,7 @@ resolve.exports@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.0.tgz#c1a0028c2d166ec2fbf7d0644584927e76e7400e"
|
||||
integrity sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg==
|
||||
|
||||
resolve@^1.10.0, resolve@^1.11.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.21.0, resolve@^1.22.0, resolve@^1.22.4, resolve@^1.9.0:
|
||||
resolve@^1.10.0, resolve@^1.11.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.21.0, resolve@^1.22.4, resolve@^1.9.0:
|
||||
version "1.22.8"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
|
||||
integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
|
||||
|
@ -19513,7 +19231,7 @@ semver-diff@^3.1.1:
|
|||
dependencies:
|
||||
semver "^6.3.0"
|
||||
|
||||
"semver@2 || 3 || 4 || 5", semver@7.5.3, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1, semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0, semver@^6.3.1, semver@^7.0.0, semver@^7.1.1, semver@^7.1.2, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@~2.3.1, semver@~7.0.0:
|
||||
"semver@2 || 3 || 4 || 5", semver@7.5.3, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1, semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0, semver@^6.3.1, semver@^7.0.0, semver@^7.1.1, semver@^7.1.2, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@~2.3.1, semver@~7.0.0:
|
||||
version "7.5.3"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e"
|
||||
integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==
|
||||
|
@ -19551,7 +19269,7 @@ server-destroy@1.0.1, server-destroy@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/server-destroy/-/server-destroy-1.0.1.tgz#f13bf928e42b9c3e79383e61cc3998b5d14e6cdd"
|
||||
integrity sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==
|
||||
|
||||
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==
|
||||
|
@ -19702,15 +19420,6 @@ simple-concat@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f"
|
||||
integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==
|
||||
|
||||
simple-get@^3.0.3:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.1.tgz#cc7ba77cfbe761036fbfce3d021af25fc5584d55"
|
||||
integrity sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==
|
||||
dependencies:
|
||||
decompress-response "^4.2.0"
|
||||
once "^1.3.1"
|
||||
simple-concat "^1.0.0"
|
||||
|
||||
simple-get@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543"
|
||||
|
@ -20210,18 +19919,6 @@ stream-events@^1.0.5:
|
|||
dependencies:
|
||||
stubs "^3.0.0"
|
||||
|
||||
stream-meter@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/stream-meter/-/stream-meter-1.0.4.tgz#52af95aa5ea760a2491716704dbff90f73afdd1d"
|
||||
integrity sha512-4sOEtrbgFotXwnEuzzsQBYEV1elAeFSO8rSGeTwabuX1RRn/kEq9JVH7I0MRBhKVRR0sJkr0M0QCH7yOLf9fhQ==
|
||||
dependencies:
|
||||
readable-stream "^2.1.4"
|
||||
|
||||
stream-read-all@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/stream-read-all/-/stream-read-all-3.0.1.tgz#60762ae45e61d93ba0978cda7f3913790052ad96"
|
||||
integrity sha512-EWZT9XOceBPlVJRrYcykW8jyRSZYbkb/0ZK36uLEmoWVO5gxBOnntNTseNzfREsqxqdfEGQrD8SXQ3QWbBmq8A==
|
||||
|
||||
stream-shift@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
|
||||
|
@ -20271,15 +19968,6 @@ string-similarity@^4.0.4:
|
|||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.1"
|
||||
|
||||
string-width@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
|
||||
integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==
|
||||
dependencies:
|
||||
code-point-at "^1.0.0"
|
||||
is-fullwidth-code-point "^1.0.0"
|
||||
strip-ansi "^3.0.0"
|
||||
|
||||
string-width@^3.0.0, string-width@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
|
||||
|
@ -20368,13 +20056,6 @@ stringify-object@^3.2.1:
|
|||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-ansi@^3.0.0, strip-ansi@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
|
||||
integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==
|
||||
dependencies:
|
||||
ansi-regex "^2.0.0"
|
||||
|
||||
strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
|
||||
|
@ -20763,22 +20444,12 @@ symbol-tree@^3.2.4:
|
|||
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
|
||||
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
|
||||
|
||||
table-layout@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04"
|
||||
integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==
|
||||
dependencies:
|
||||
array-back "^4.0.1"
|
||||
deep-extend "~0.6.0"
|
||||
typical "^5.2.0"
|
||||
wordwrapjs "^4.0.0"
|
||||
|
||||
tapable@^2.1.1, tapable@^2.2.0:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
|
||||
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
|
||||
|
||||
tar-fs@2.1.1, tar-fs@^2.0.0, tar-fs@^2.1.0, tar-fs@^2.1.1:
|
||||
tar-fs@2.1.1, tar-fs@^2.0.0, tar-fs@^2.1.0:
|
||||
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==
|
||||
|
@ -21462,21 +21133,6 @@ typescript@^4.0.0, typescript@^4.5.5:
|
|||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
|
||||
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
|
||||
|
||||
typical@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4"
|
||||
integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==
|
||||
|
||||
typical@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066"
|
||||
integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==
|
||||
|
||||
typical@^7.1.1:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/typical/-/typical-7.1.1.tgz#ba177ab7ab103b78534463ffa4c0c9754523ac1f"
|
||||
integrity sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==
|
||||
|
||||
typo-js@*:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/typo-js/-/typo-js-1.2.2.tgz#340484d81fe518e77c81a5a770162b14492f183b"
|
||||
|
@ -22219,7 +21875,7 @@ why-is-node-running@^2.2.2:
|
|||
siginfo "^2.0.0"
|
||||
stackback "0.0.2"
|
||||
|
||||
wide-align@^1.1.0, wide-align@^1.1.2, wide-align@^1.1.5:
|
||||
wide-align@^1.1.2, wide-align@^1.1.5:
|
||||
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==
|
||||
|
@ -22274,14 +21930,6 @@ wordwrap@^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"
|
||||
integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==
|
||||
dependencies:
|
||||
reduce-flatten "^2.0.0"
|
||||
typical "^5.2.0"
|
||||
|
||||
worker-farm@1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8"
|
||||
|
|
Loading…
Reference in New Issue