This commit is contained in:
Rory Powell 2023-05-17 14:10:22 +01:00
parent ad37186665
commit 578b599428
13 changed files with 465 additions and 32 deletions

View File

@ -104,13 +104,17 @@ async function newContext(updates: ContextMap, task: any) {
return Context.run(context, task) return Context.run(context, task)
} }
export async function doInAutomationContext(appId: string, automationId: string, task: any): Promise<any> { export async function doInAutomationContext(
appId: string,
automationId: string,
task: any
): Promise<any> {
const tenantId = getTenantIDFromAppID(appId) const tenantId = getTenantIDFromAppID(appId)
return newContext( return newContext(
{ {
tenantId, tenantId,
appId, appId,
automationId automationId,
}, },
task task
) )

View File

@ -36,8 +36,8 @@ function getLogParams(
eventType: QueueEventType, eventType: QueueEventType,
event: BullEvent, event: BullEvent,
opts: { opts: {
job?: Job, job?: Job
jobId?: JobId, jobId?: JobId
error?: Error error?: Error
} = {}, } = {},
extra: any = {} extra: any = {}
@ -50,32 +50,32 @@ function getLogParams(
event, event,
job: opts.job, job: opts.job,
jobId: opts.jobId || opts.job?.id, jobId: opts.jobId || opts.job?.id,
...extra ...extra,
} }
return [message, err, data] return [message, err, data]
} }
enum BullEvent { enum BullEvent {
ERROR="error", ERROR = "error",
WAITING="waiting", WAITING = "waiting",
ACTIVE="active", ACTIVE = "active",
STALLED="stalled", STALLED = "stalled",
PROGRESS="progress", PROGRESS = "progress",
COMPLETED="completed", COMPLETED = "completed",
FAILED="failed", FAILED = "failed",
PAUSED="paused", PAUSED = "paused",
RESUMED="resumed", RESUMED = "resumed",
CLEANED="cleaned", CLEANED = "cleaned",
DRAINED="drained", DRAINED = "drained",
REMOVED="removed", REMOVED = "removed",
} }
enum QueueEventType { enum QueueEventType {
AUTOMATION_EVENT="automation-event", AUTOMATION_EVENT = "automation-event",
APP_BACKUP_EVENT="app-backup-event", APP_BACKUP_EVENT = "app-backup-event",
AUDIT_LOG_EVENT="audit-log-event", AUDIT_LOG_EVENT = "audit-log-event",
SYSTEM_EVENT="system-event" SYSTEM_EVENT = "system-event",
} }
const EventTypeMap: { [key in JobQueue]: QueueEventType } = { const EventTypeMap: { [key in JobQueue]: QueueEventType } = {
@ -126,19 +126,30 @@ function logging(queue: Queue, jobQueue: JobQueue) {
.on(BullEvent.PROGRESS, async (job: Job, progress: any) => { .on(BullEvent.PROGRESS, async (job: Job, progress: any) => {
// A job's progress was updated // A job's progress was updated
await doInJobContext(job, () => { await doInJobContext(job, () => {
console.info(...getLogParams(eventType, BullEvent.PROGRESS, { job }, { progress })) console.info(
...getLogParams(
eventType,
BullEvent.PROGRESS,
{ job },
{ progress }
)
)
}) })
}) })
.on(BullEvent.COMPLETED, async (job: Job, result) => { .on(BullEvent.COMPLETED, async (job: Job, result) => {
// A job successfully completed with a `result`. // A job successfully completed with a `result`.
await doInJobContext(job, () => { await doInJobContext(job, () => {
console.info(...getLogParams(eventType, BullEvent.COMPLETED, { job }, { result })) console.info(
...getLogParams(eventType, BullEvent.COMPLETED, { job }, { result })
)
}) })
}) })
.on(BullEvent.FAILED, async (job: Job, error: any) => { .on(BullEvent.FAILED, async (job: Job, error: any) => {
// A job failed with reason `err`! // A job failed with reason `err`!
await doInJobContext(job, () => { await doInJobContext(job, () => {
console.error(...getLogParams(eventType, BullEvent.FAILED, { job, error })) console.error(
...getLogParams(eventType, BullEvent.FAILED, { job, error })
)
}) })
}) })
.on(BullEvent.PAUSED, () => { .on(BullEvent.PAUSED, () => {
@ -152,15 +163,22 @@ function logging(queue: Queue, jobQueue: JobQueue) {
.on(BullEvent.CLEANED, (jobs: Job[], type: string) => { .on(BullEvent.CLEANED, (jobs: Job[], type: string) => {
// Old jobs have been cleaned from the queue. `jobs` is an array of cleaned // Old jobs have been cleaned from the queue. `jobs` is an array of cleaned
// jobs, and `type` is the type of jobs cleaned. // jobs, and `type` is the type of jobs cleaned.
console.info(...getLogParams(eventType, BullEvent.CLEANED, {}, { length: jobs.length, type } )) console.info(
...getLogParams(
eventType,
BullEvent.CLEANED,
{},
{ length: jobs.length, type }
)
)
}) })
.on(BullEvent.DRAINED, () => { .on(BullEvent.DRAINED, () => {
// Emitted every time the queue has processed all the waiting jobs (even if there can be some delayed jobs not yet processed) // Emitted every time the queue has processed all the waiting jobs (even if there can be some delayed jobs not yet processed)
console.info(...getLogParams(eventType, BullEvent.DRAINED )) console.info(...getLogParams(eventType, BullEvent.DRAINED))
}) })
.on(BullEvent.REMOVED, (job: Job) => { .on(BullEvent.REMOVED, (job: Job) => {
// A job successfully removed. // A job successfully removed.
console.info(...getLogParams(eventType, BullEvent.REMOVED, { job } )) console.info(...getLogParams(eventType, BullEvent.REMOVED, { job }))
}) })
} }
} }

View File

@ -0,0 +1,140 @@
# Console Control Strings
A library of cross-platform tested terminal/console command strings for
doing things like color and cursor positioning. This is a subset of both
ansi and vt100. All control codes included work on both Windows & Unix-like
OSes, except where noted.
## Usage
```js
var consoleControl = require('console-control-strings')
console.log(consoleControl.color('blue','bgRed', 'bold') + 'hi there' + consoleControl.color('reset'))
process.stdout.write(consoleControl.goto(75, 10))
```
## Why Another?
There are tons of libraries similar to this one. I wanted one that was:
1. Very clear about compatibility goals.
2. Could emit, for instance, a start color code without an end one.
3. Returned strings w/o writing to streams.
4. Was not weighed down with other unrelated baggage.
## Functions
### var code = consoleControl.up(_num = 1_)
Returns the escape sequence to move _num_ lines up.
### var code = consoleControl.down(_num = 1_)
Returns the escape sequence to move _num_ lines down.
### var code = consoleControl.forward(_num = 1_)
Returns the escape sequence to move _num_ lines righ.
### var code = consoleControl.back(_num = 1_)
Returns the escape sequence to move _num_ lines left.
### var code = consoleControl.nextLine(_num = 1_)
Returns the escape sequence to move _num_ lines down and to the beginning of
the line.
### var code = consoleControl.previousLine(_num = 1_)
Returns the escape sequence to move _num_ lines up and to the beginning of
the line.
### var code = consoleControl.eraseData()
Returns the escape sequence to erase everything from the current cursor
position to the bottom right of the screen. This is line based, so it
erases the remainder of the current line and all following lines.
### var code = consoleControl.eraseLine()
Returns the escape sequence to erase to the end of the current line.
### var code = consoleControl.goto(_x_, _y_)
Returns the escape sequence to move the cursor to the designated position.
Note that the origin is _1, 1_ not _0, 0_.
### var code = consoleControl.gotoSOL()
Returns the escape sequence to move the cursor to the beginning of the
current line. (That is, it returns a carriage return, `\r`.)
### var code = consoleControl.hideCursor()
Returns the escape sequence to hide the cursor.
### var code = consoleControl.showCursor()
Returns the escape sequence to show the cursor.
### var code = consoleControl.color(_colors = []_)
### var code = consoleControl.color(_color1_, _color2_, _…_, _colorn_)
Returns the escape sequence to set the current terminal display attributes
(mostly colors). Arguments can either be a list of attributes or an array
of attributes. The difference between passing in an array or list of colors
and calling `.color` separately for each one, is that in the former case a
single escape sequence will be produced where as in the latter each change
will have its own distinct escape sequence. Each attribute can be one of:
* Reset:
* **reset** Reset all attributes to the terminal default.
* Styles:
* **bold** Display text as bold. In some terminals this means using a
bold font, in others this means changing the color. In some it means
both.
* **italic** Display text as italic. This is not available in most Windows terminals.
* **underline** Underline text. This is not available in most Windows Terminals.
* **inverse** Invert the foreground and background colors.
* **stopBold** Do not display text as bold.
* **stopItalic** Do not display text as italic.
* **stopUnderline** Do not underline text.
* **stopInverse** Do not invert foreground and background.
* Colors:
* **white**
* **black**
* **blue**
* **cyan**
* **green**
* **magenta**
* **red**
* **yellow**
* **grey** / **brightBlack**
* **brightRed**
* **brightGreen**
* **brightYellow**
* **brightBlue**
* **brightMagenta**
* **brightCyan**
* **brightWhite**
* Background Colors:
* **bgWhite**
* **bgBlack**
* **bgBlue**
* **bgCyan**
* **bgGreen**
* **bgMagenta**
* **bgRed**
* **bgYellow**
* **bgGrey** / **bgBrightBlack**
* **bgBrightRed**
* **bgBrightGreen**
* **bgBrightYellow**
* **bgBrightBlue**
* **bgBrightMagenta**
* **bgBrightCyan**
* **bgBrightWhite**

127
packages/pro/node_modules/copy-concurrently/README.md~ generated vendored Normal file
View File

@ -0,0 +1,127 @@
# copy-concurrently
Copy files, directories and symlinks
```
const copy = require('copy-concurrently')
copy('/path/to/thing', '/new/path/thing').then(() => {
// this is now copied
}).catch(err => {
// oh noooo
})
```
Copies files, directories and symlinks. Ownership is maintained when
running as root, permissions are always maintained. On Windows, if symlinks
are unavailable then junctions will be used.
## PUBLIC INTERFACE
### copy(from, to, [options]) → Promise
Recursively copies `from` to `to` and resolves its promise when finished.
If `to` already exists then the promise will be rejected with an `EEXIST`
error.
Options are:
* maxConcurrency (Default: `1`) The maximum number of concurrent copies to do at once.
* recurseWith - (Default: `copy.item`) The function to call on each file after recursing into a directory.
* isWindows - (Default: `process.platform === 'win32'`) If true enables Windows symlink semantics. This requires
an extra `stat` to determine if the destination of a symlink is a file or directory. If symlinking a directory
fails then we'll try making a junction instead.
Options can also include dependency injection:
* Promise - (Default: `global.Promise`) The promise implementation to use, defaults to Node's.
* fs - (Default: `require('fs')`) The filesystem module to use. Can be used
to use `graceful-fs` or to inject a mock.
* writeStreamAtomic - (Default: `require('fs-write-stream-atomic')`) The
implementation of `writeStreamAtomic` to use. Used to inject a mock.
* getuid - (Default: `process.getuid`) A function that returns the current UID. Used to inject a mock.
## EXTENSION INTERFACE
Ordinarily you'd only call `copy` above. But it's possible to use it's
component functions directly. This is useful if, say, you're writing
[move-concurently](https://npmjs.com/package/move-concurrently).
### copy.file(from, to, options) → Promise
Copies a ordinary file `from` to destination `to`. Uses
`fs-write-stream-atomic` to ensure that the file is entirely copied or not
at all.
Options are:
* uid, gid - (Optional) If `getuid()` is `0` then this and gid will be used to
set the user and group of `to`. If uid is present then gid must be too.
* mode - (Optional) If set then `to` will have its perms set to `mode`.
* fs - (Default: `require('fs')`) The filesystem module to use. Can be used
to use `graceful-fs` or to inject a mock.
* Promise - (Default: `global.Promise`) The promise implementation to use, defaults to Node's.
* writeStreamAtomic - (Default `require('fs-write-stream-atomic')`) The
implementation of `writeStreamAtomic` to use. Used to inject a mock.
### copy.symlink(from, to, options) → Promise
Copies a symlink `from` to destination `to`. If on Windows then if
symlinking fails, a junction will be used instead.
Options are:
* top - The top level the copy is being run from. This is used to determine
if the symlink destination is within the set of files we're copying or
outside it.
* fs - (Default: `require('fs')`) The filesystem module to use. Can be used
to use `graceful-fs` or to inject a mock.
* Promise - (Default: `global.Promise`) The promise implementation to use, defaults to Node's.
* isWindows - (Default: `process.platform === 'win32'`) If true enables Windows symlink semantics. This requires
an extra `stat` to determine if the destination of a symlink is a file or directory. If symlinking a directory
fails then we'll try making a junction instead.
### copy.recurse(from, to, options) → Promise
Reads all of the files in directory `from` and adds them to the `queue`
using `recurseWith` (by default `copy.item`).
Options are:
* queue - A [`run-queue`](https://npmjs.com/package/run-queue) object to add files found inside `from` to.
* recurseWith - (Default: `copy.item`) The function to call on each file after recursing into a directory.
* uid, gid - (Optional) If `getuid()` is `0` then this and gid will be used to
set the user and group of `to`. If uid is present then gid must be too.
* mode - (Optional) If set then `to` will have its perms set to `mode`.
* fs - (Default: `require('fs')`) The filesystem module to use. Can be used
to use `graceful-fs` or to inject a mock.
* getuid - (Default: `process.getuid`) A function that returns the current UID. Used to inject a mock.
### copy.item(from, to, options) → Promise
Copies some kind of `from` to destination `to`. This looks at the filetype
and calls `copy.file`, `copy.symlink` or `copy.recurse` as appropriate.
Symlink copies are queued with a priority such that they happen after all
file and directory copies as you can't create a junction on windows to a
file that doesn't exist yet.
Options are:
* top - The top level the copy is being run from. This is used to determine
if the symlink destination is within the set of files we're copying or
outside it.
* queue - The [`run-queue`](https://npmjs.com/package/run-queue) object to
pass to `copy.recurse` if `from` is a directory.
* recurseWith - (Default: `copy.item`) The function to call on each file after recursing into a directory.
* uid, gid - (Optional) If `getuid()` is `0` then this and gid will be used to
set the user and group of `to`. If uid is present then gid must be too.
* mode - (Optional) If set then `to` will have its perms set to `mode`.
* fs - (Default: `require('fs')`) The filesystem module to use. Can be used
to use `graceful-fs` or to inject a mock.
* getuid - (Default: `process.getuid`) A function that returns the current UID. Used to inject a mock.
* isWindows - (Default: `process.platform === 'win32'`) If true enables Windows symlink semantics. This requires
an extra `stat` to determine if the destination of a symlink is a file or directory. If symlinking a directory
fails then we'll try making a junction instead.
* Promise - (Default: `global.Promise`) The promise implementation to use, defaults to Node's.
* writeStreamAtomic - (Default `require('fs-write-stream-atomic')`) The
implementation of `writeStreamAtomic` to use. Used to inject a mock.

52
packages/pro/node_modules/move-concurrently/README.md~ generated vendored Normal file
View File

@ -0,0 +1,52 @@
# move-concurrently
Move files and directories.
```
const move = require('move-concurrently')
move('/path/to/thing', '/new/path/thing'), err => {
if (err) throw err
// thing is now moved!
})
```
Uses `rename` to move things as fast as possible.
If you `move` across devices or on filesystems that don't support renaming
large directories. That is, situations that result in `rename` returning
the `EXDEV` error, then `move` will fallback to copy + delete.
When recursively copying directories it will first try to rename the
contents before falling back to copying. While this will be slightly slower
in true cross-device scenarios, it is MUCH faster in cases where the
filesystem can't handle directory renames.
When copying ownership is maintained when running as root. Permissions are
always maintained. On Windows, if symlinks are unavailable then junctions
will be used.
## INTERFACE
### move(from, to, options) → Promise
Recursively moves `from` to `to` and resolves its promise when finished.
If `to` already exists then the promise will be rejected with an `EEXIST`
error.
Starts by trying to rename `from` to `to`.
Options are:
* maxConcurrency (Default: `1`) The maximum number of concurrent copies to do at once.
* isWindows - (Default: `process.platform === 'win32'`) If true enables Windows symlink semantics. This requires
an extra `stat` to determine if the destination of a symlink is a file or directory. If symlinking a directory
fails then we'll try making a junction instead.
Options can also include dependency injection:
* Promise - (Default: `global.Promise`) The promise implementation to use, defaults to Node's.
* fs - (Default: `require('fs')`) The filesystem module to use. Can be used
to use `graceful-fs` or to inject a mock.
* writeStreamAtomic - (Default: `require('fs-write-stream-atomic')`) The
implementation of `writeStreamAtomic` to use. Used to inject a mock.
* getuid - (Default: `process.getuid`) A function that returns the current UID. Used to inject a mock.

68
packages/pro/node_modules/umask/index.js~ generated vendored Normal file
View File

@ -0,0 +1,68 @@
// commands for handling umask
var util = require("util")
var log = require("npmlog")
var defaultUmask = 0022
var defaultUmaskString = toString(defaultUmask)
exports.toString = toString
exports.fromString = fromString
exports.validate = validate
function toString(val) {
val = val.toString(8)
while (val.length < 4) val = "0" + val
return val
}
function validate (data, k, val) {
// must be either an integer or an octal string.
if (typeof val === "number") {
data[k] = val
return true
}
if (typeof val === "string") {
if (val.charAt(0) !== "0" || isNaN(val)) return false
data[k] = parseInt(val, 8)
return true
}
return false
}
function fromString(val, cb) {
// synchronous callback, no zalgo
_fromString(val, cb || function (err, result) {
if (err) log.warn("invalid umask", err.message)
val = result
})
return val
}
function _fromString(val, cb) {
if(typeof val === "string") {
if (!/^[0-7]+$/.test(val)) {
return cb(new Error(util.format("Expected octal string, got %j, defaulting to %j",
val, defaultUmaskString)),
defaultUmask)
}
val = parseInt(val, 8)
} else if(typeof val !== "number") {
return cb(new Error(util.format("Expected number or octal string, got %j, defaulting to %j",
val, defaultUmaskString)),
defaultUmask)
}
if ((val < 0) || (val > 511)) {
return cb(new Error(util.format("Must be in range 0..511 (0000..0777), got %j", val)),
defaultUmask)
}
cb(null, val)
}

5
packages/pro/node_modules/umask/test/ChangeLog~ generated vendored Normal file
View File

@ -0,0 +1,5 @@
2015-01-15 Sam Mikes <smikes@Svarog.local>
* index.js: (convert_fromString) accept decimal strings provided they
don't begin with '0'

14
packages/pro/node_modules/umask/test/simple.js~ generated vendored Normal file
View File

@ -0,0 +1,14 @@
'use strict';
var Purefts = require('..');
var Code = require('code');
var Lab = require('lab');
var lab = Lab.script();
exports.lab = lab;
var describe = lab.describe;
var it = lab.it;
var expect = Code.expect;
describe('create objects', function () {

View File

@ -19,7 +19,7 @@ const Runner = new Thread(ThreadType.AUTOMATION)
function loggingArgs(job: AutomationJob) { function loggingArgs(job: AutomationJob) {
return { return {
jobId: job.id, jobId: job.id,
trigger: job.data.automation.definition.trigger.event trigger: job.data.automation.definition.trigger.event,
} }
} }

View File

@ -27,4 +27,3 @@ export interface AutomationContext extends AutomationResults {
env?: Record<string, string> env?: Record<string, string>
trigger: any trigger: any
} }

View File

@ -13,7 +13,13 @@ import { generateAutomationMetadataID, isProdAppID } from "../db/utils"
import { definitions as triggerDefs } from "../automations/triggerInfo" import { definitions as triggerDefs } from "../automations/triggerInfo"
import { AutomationErrors, MAX_AUTOMATION_RECURRING_ERRORS } from "../constants" import { AutomationErrors, MAX_AUTOMATION_RECURRING_ERRORS } from "../constants"
import { storeLog } from "../automations/logging" import { storeLog } from "../automations/logging"
import { Automation, AutomationStep, AutomationStatus, AutomationMetadata, AutomationJob } from "@budibase/types" import {
Automation,
AutomationStep,
AutomationStatus,
AutomationMetadata,
AutomationJob,
} from "@budibase/types"
import { import {
LoopStep, LoopStep,
LoopInput, LoopInput,