diff --git a/packages/builder/package.json b/packages/builder/package.json index 086d22382a..0926b82fb0 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -47,9 +47,11 @@ "lodash": "^4.17.13", "logrocket": "^1.0.6", "lunr": "^2.3.5", + "mustache": "^4.0.1", "safe-buffer": "^5.1.2", "shortid": "^2.2.8", "string_decoder": "^1.2.0", + "svelte-grid": "^1.10.8", "svelte-simple-modal": "^0.3.0", "uikit": "^3.1.7" }, diff --git a/packages/builder/src/builderStore/api.js b/packages/builder/src/builderStore/api.js index c9327a98f2..04dcce6cb9 100644 --- a/packages/builder/src/builderStore/api.js +++ b/packages/builder/src/builderStore/api.js @@ -25,5 +25,5 @@ export default { get, patch, delete: del, - put + put, } diff --git a/packages/builder/src/builderStore/index.js b/packages/builder/src/builderStore/index.js index dd6784c135..2af3a66667 100644 --- a/packages/builder/src/builderStore/index.js +++ b/packages/builder/src/builderStore/index.js @@ -1,6 +1,6 @@ import { getStore } from "./store" import { getBackendUiStore } from "./store/backend" -import { getWorkflowStore } from "./store/workflow" +import { getWorkflowStore } from "./store/workflow/" import LogRocket from "logrocket" export const store = getStore() diff --git a/packages/builder/src/builderStore/store/workflow.js b/packages/builder/src/builderStore/store/workflow.js deleted file mode 100644 index f1eb8b93f5..0000000000 --- a/packages/builder/src/builderStore/store/workflow.js +++ /dev/null @@ -1,55 +0,0 @@ -import { writable } from "svelte/store" -import api from "../api" - -const workflowActions = store => ({ - fetch: async instanceId => { - const WORKFLOWS_URL = `/api/${instanceId}/workflows`; - const workflowResponse = await api.get(WORKFLOWS_URL); - const json = await workflowResponse.json(); - store.update(state => { - state.workflows = json - return state - }) - }, - create: async ({ instanceId, name }) => { - const workflow = { name } - const CREATE_WORKFLOW_URL = `/api/${instanceId}/workflows`; - const response = await api.post(CREATE_WORKFLOW_URL, workflow) - const json = await response.json(); - store.update(state => { - state.workflows = state.workflows.concat(json.workflow) - state.selectedWorkflowId = json.workflow._id - return state - }) - }, - update: async ({ instanceId, workflow }) => { - const UPDATE_WORKFLOW_URL = `/api/${instanceId}/workflows`; - const response = await api.put(UPDATE_WORKFLOW_URL, workflow) - const json = await response.json(); - store.update(state => { - const existingIdx = state.workflows.findIndex(existing => existing._id === workflow._id); - state.workflows.splice(existingIdx, 1, json.workflow); - state.workflows = state.workflows - return state - }) - }, - select: workflow => { - store.update(state => { - state.selectedWorkflowId = workflow._id - state.selectedWorkflowBlock = null - return state; - }) - } -}); - -export const getWorkflowStore = () => { - const INITIAL_WORKFLOW_STATE = { - workflows: [] - } - - const store = writable(INITIAL_WORKFLOW_STATE) - - store.actions = workflowActions(store); - - return store -} \ No newline at end of file diff --git a/packages/builder/src/builderStore/store/workflow/Workflow.js b/packages/builder/src/builderStore/store/workflow/Workflow.js new file mode 100644 index 0000000000..b3e50466f7 --- /dev/null +++ b/packages/builder/src/builderStore/store/workflow/Workflow.js @@ -0,0 +1,79 @@ +import mustache from "mustache" +// TODO: tidy up import +import blockDefinitions from "../../../pages/[application]/workflow/WorkflowPanel/blockDefinitions" + +/** + * Class responsible for the traversing of the workflow definition. + * Workflow definitions are stored in linked lists. + */ +export default class Workflow { + constructor(workflow) { + this.workflow = workflow + } + + addBlock(block) { + let node = this.workflow.definition + while (node.next) node = node.next + node.next = block + } + + updateBlock(updatedBlock, id) { + let block = this.workflow.definition + + while (block.id !== id) block = block.next + if (!block) throw new Error("Block not found.") + + block = updatedBlock + } + + deleteBlock(id) { + let previous = null + let block = this.workflow.definition + + // iterate through the blocks + while (block.id !== id) { + previous = block + block = block.next + } + + // delete the block found + previous.next = block.next || {} + } + + createUiTree() { + if (!this.workflow.definition.next) return [] + return Workflow.buildUiTree(this.workflow.definition.next) + } + + static buildUiTree(block, tree = []) { + if (!block) return tree + + // The client side display definition for the block + const definition = blockDefinitions[block.type][block.actionId] + if (!definition) { + throw new Error( + `No block definition exists for the chosen block. Check there's an entry in the block definitions for ${block.actionId}` + ) + } + + if (!definition.params) { + throw new Error( + `Blocks should always have parameters. Ensure that the block definition is correct for ${block.actionId}` + ) + } + + const tagline = definition.tagline || "" + const args = block.args || {} + + tree.push({ + id: block.id, + type: block.type, + params: block.params, + args, + heading: block.actionId, + body: mustache.render(tagline, args), + }) + + return this.buildUiTree(block.next, tree) + } +} diff --git a/packages/builder/src/builderStore/store/workflow/index.js b/packages/builder/src/builderStore/store/workflow/index.js new file mode 100644 index 0000000000..fcdc299271 --- /dev/null +++ b/packages/builder/src/builderStore/store/workflow/index.js @@ -0,0 +1,102 @@ +import { writable } from "svelte/store" +import api from "../../api" +import Workflow from "./Workflow" + +const workflowActions = store => ({ + fetch: async instanceId => { + const WORKFLOWS_URL = `/api/${instanceId}/workflows` + const workflowResponse = await api.get(WORKFLOWS_URL) + const json = await workflowResponse.json() + store.update(state => { + state.workflows = json + return state + }) + }, + create: async ({ instanceId, name }) => { + const workflow = { name, definition: {} } + const CREATE_WORKFLOW_URL = `/api/${instanceId}/workflows` + const response = await api.post(CREATE_WORKFLOW_URL, workflow) + const json = await response.json() + store.update(state => { + state.workflows = state.workflows.concat(json.workflow) + state.currentWorkflow = new Workflow(json.workflow) + return state + }) + }, + save: async ({ instanceId, workflow }) => { + const UPDATE_WORKFLOW_URL = `/api/${instanceId}/workflows` + const response = await api.put(UPDATE_WORKFLOW_URL, workflow) + const json = await response.json() + store.update(state => { + const existingIdx = state.workflows.findIndex( + existing => existing._id === workflow._id + ) + state.workflows.splice(existingIdx, 1, json.workflow) + state.workflows = state.workflows + state.currentWorkflow = new Workflow(json.workflow) + return state + }) + }, + update: async ({ instanceId, workflow }) => { + const UPDATE_WORKFLOW_URL = `/api/${instanceId}/workflows` + const response = await api.put(UPDATE_WORKFLOW_URL, workflow) + const json = await response.json() + store.update(state => { + const existingIdx = state.workflows.findIndex( + existing => existing._id === workflow._id + ) + state.workflows.splice(existingIdx, 1, json.workflow) + state.workflows = state.workflows + return state + }) + }, + delete: async ({ instanceId, workflow }) => { + const { _id, _rev } = workflow + const DELETE_WORKFLOW_URL = `/api/${instanceId}/workflows/${_id}/${_rev}` + await api.delete(DELETE_WORKFLOW_URL) + + store.update(state => { + const existingIdx = state.workflows.findIndex( + existing => existing._id === _id + ) + state.workflows.splice(existingIdx, 1) + state.workflows = state.workflows + state.currentWorkflow = null + return state + }) + }, + select: workflow => { + store.update(state => { + // TODO: better naming + state.currentWorkflow = new Workflow(workflow) + state.selectedWorkflowBlock = null + return state + }) + }, + addBlockToWorkflow: block => { + store.update(state => { + state.currentWorkflow.addBlock(block) + state.selectedWorkflowBlock = block + return state + }) + }, + deleteWorkflowBlock: block => { + store.update(state => { + state.currentWorkflow.deleteBlock(block._id) + state.selectedWorkflowBlock = null + return state + }) + }, +}) + +export const getWorkflowStore = () => { + const INITIAL_WORKFLOW_STATE = { + workflows: [], + } + + const store = writable(INITIAL_WORKFLOW_STATE) + + store.actions = workflowActions(store) + + return store +} diff --git a/packages/builder/src/builderStore/store/workflow/tests/Workflow.js b/packages/builder/src/builderStore/store/workflow/tests/Workflow.js new file mode 100644 index 0000000000..a892d688b3 --- /dev/null +++ b/packages/builder/src/builderStore/store/workflow/tests/Workflow.js @@ -0,0 +1 @@ +describe("Workflow Data Object", () => {}) diff --git a/packages/builder/src/components/database/ModelDataTable/modals/CreateUser.svelte b/packages/builder/src/components/database/ModelDataTable/modals/CreateUser.svelte index 77e0850b87..e81659f716 100644 --- a/packages/builder/src/components/database/ModelDataTable/modals/CreateUser.svelte +++ b/packages/builder/src/components/database/ModelDataTable/modals/CreateUser.svelte @@ -34,7 +34,7 @@
diff --git a/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte b/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte index a255e92d90..c2cee9e6af 100644 --- a/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte +++ b/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte @@ -25,7 +25,7 @@ let categories = [ { value: "design", name: "Design" }, { value: "settings", name: "Settings" }, - { value: "events", name: "Events" } + { value: "events", name: "Events" }, ] let selectedCategory = categories[0] diff --git a/packages/builder/src/global.css b/packages/builder/src/global.css index 7edc1c6d40..852c5f044b 100644 --- a/packages/builder/src/global.css +++ b/packages/builder/src/global.css @@ -78,6 +78,7 @@ --primary: #0055ff; --secondary: #f1f4fc; --color: #393c44; + --light-grey: #fbfbfb; --dark-grey: #808192; --medium-grey: #e8e8ef; --background: rgb(251, 251, 251); diff --git a/packages/builder/src/pages/[application]/workflow/SetupPanel/DeleteWorkflowModal.svelte b/packages/builder/src/pages/[application]/workflow/SetupPanel/DeleteWorkflowModal.svelte new file mode 100644 index 0000000000..82af963cfc --- /dev/null +++ b/packages/builder/src/pages/[application]/workflow/SetupPanel/DeleteWorkflowModal.svelte @@ -0,0 +1,87 @@ + + +
+ + Delete Workflow +
+
+

+ Are you sure you want to delete this workflow? This action can't be undone. +

+
+ + + diff --git a/packages/builder/src/pages/[application]/workflow/SetupPanel/ParamInputs/ComponentParam.svelte b/packages/builder/src/pages/[application]/workflow/SetupPanel/ParamInputs/ComponentParam.svelte new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/builder/src/pages/[application]/workflow/SetupPanel/ParamInputs/ModelParam.svelte b/packages/builder/src/pages/[application]/workflow/SetupPanel/ParamInputs/ModelParam.svelte new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/builder/src/pages/[application]/workflow/SetupPanel/ParamInputs/NumberParam.svelte b/packages/builder/src/pages/[application]/workflow/SetupPanel/ParamInputs/NumberParam.svelte new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/builder/src/pages/[application]/workflow/SetupPanel/ParamInputs/StringParam.svelte b/packages/builder/src/pages/[application]/workflow/SetupPanel/ParamInputs/StringParam.svelte new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/builder/src/pages/[application]/workflow/SetupPanel/SetupPanel.svelte b/packages/builder/src/pages/[application]/workflow/SetupPanel/SetupPanel.svelte index 1bfd17779a..b23e7f4c4a 100644 --- a/packages/builder/src/pages/[application]/workflow/SetupPanel/SetupPanel.svelte +++ b/packages/builder/src/pages/[application]/workflow/SetupPanel/SetupPanel.svelte @@ -1,20 +1,27 @@ @@ -26,10 +33,12 @@
{#if workflowBlock} - - {:else if $workflowStore.selectedWorkflowId} + {:else if $workflowStore.currentWorkflow}
@@ -44,7 +53,9 @@ Some User Access Stuff Here
- {/if} diff --git a/packages/builder/src/pages/[application]/workflow/SetupPanel/WorkflowBlockSetup.svelte b/packages/builder/src/pages/[application]/workflow/SetupPanel/WorkflowBlockSetup.svelte index 1613a78f18..f3d0bdaba8 100644 --- a/packages/builder/src/pages/[application]/workflow/SetupPanel/WorkflowBlockSetup.svelte +++ b/packages/builder/src/pages/[application]/workflow/SetupPanel/WorkflowBlockSetup.svelte @@ -1,17 +1,62 @@ - -{#each workflowArgs as workflowArg} -
- + +{#each workflowParams as [parameter, type]} +
+
- + {#if type === 'number'} + + {:else if type === 'model'} + + {:else if type === 'component'} + + {:else if type === 'string'} + + {/if}
{/each} + + diff --git a/packages/builder/src/pages/[application]/workflow/SetupPanel/index.js b/packages/builder/src/pages/[application]/workflow/SetupPanel/index.js index 800406ff7a..ccfbddaf1c 100644 --- a/packages/builder/src/pages/[application]/workflow/SetupPanel/index.js +++ b/packages/builder/src/pages/[application]/workflow/SetupPanel/index.js @@ -1 +1 @@ -export { default as SetupPanel } from "./SetupPanel.svelte"; \ No newline at end of file +export { default as SetupPanel } from "./SetupPanel.svelte" diff --git a/packages/builder/src/pages/[application]/workflow/WorkflowBuilder/WorkflowBuilder.svelte b/packages/builder/src/pages/[application]/workflow/WorkflowBuilder/WorkflowBuilder.svelte index b9e43e7847..70f37e2638 100644 --- a/packages/builder/src/pages/[application]/workflow/WorkflowBuilder/WorkflowBuilder.svelte +++ b/packages/builder/src/pages/[application]/workflow/WorkflowBuilder/WorkflowBuilder.svelte @@ -9,29 +9,13 @@ let uiTree let instanceId = $backendUiStore.selectedDatabase._id - $: workflow = $workflowStore.workflows.find( - wf => wf._id === $workflowStore.selectedWorkflowId - ) + $: workflow = $workflowStore.currentWorkflow - // Build a renderable UI Tree for the flowchart generator - function buildUiTree(block, tree = []) { - if (!block) return tree - - tree.push({ - type: block.type, - heading: block.actionId, - args: block.args, - body: JSON.stringify(block.args), - }) - - return buildUiTree(block.next, tree) - } - - $: if (workflow) uiTree = workflow.definition ? buildUiTree(workflow.definition.next) : [] + $: if (workflow) uiTree = workflow ? workflow.createUiTree() : [] function onDelete(block) { // TODO finish - workflowStore.actions.deleteWorkflowBlock(block); + workflowStore.actions.deleteWorkflowBlock(block) } function onSelect(block) { @@ -43,9 +27,45 @@
- + +
+ + +
+ + diff --git a/packages/builder/src/pages/[application]/workflow/WorkflowBuilder/svelte-flows/FlowChart.svelte b/packages/builder/src/pages/[application]/workflow/WorkflowBuilder/svelte-flows/FlowChart.svelte index d444c14848..dc35b682c4 100644 --- a/packages/builder/src/pages/[application]/workflow/WorkflowBuilder/svelte-flows/FlowChart.svelte +++ b/packages/builder/src/pages/[application]/workflow/WorkflowBuilder/svelte-flows/FlowChart.svelte @@ -7,9 +7,9 @@
{#each blocks as block, idx} - + {#if idx !== blocks.length - 1} - + {/if} {/each}
diff --git a/packages/builder/src/pages/[application]/workflow/WorkflowBuilder/svelte-flows/FlowItem.svelte b/packages/builder/src/pages/[application]/workflow/WorkflowBuilder/svelte-flows/FlowItem.svelte index d533e01fa8..858d7dc075 100644 --- a/packages/builder/src/pages/[application]/workflow/WorkflowBuilder/svelte-flows/FlowItem.svelte +++ b/packages/builder/src/pages/[application]/workflow/WorkflowBuilder/svelte-flows/FlowItem.svelte @@ -3,19 +3,22 @@ export let block function selectBlock() { - onSelect(block); + onSelect(block) } + + console.log(block) -
+
{block.heading}

-

{block.body}

+

+ {@html block.body} +

diff --git a/packages/builder/src/pages/[application]/workflow/WorkflowPanel/blockDefinitions.js b/packages/builder/src/pages/[application]/workflow/WorkflowPanel/blockDefinitions.js index 5920070a7a..c0d81b95e8 100644 --- a/packages/builder/src/pages/[application]/workflow/WorkflowPanel/blockDefinitions.js +++ b/packages/builder/src/pages/[application]/workflow/WorkflowPanel/blockDefinitions.js @@ -1,89 +1,126 @@ -const ACTIONS = { +const ACTION = { SET_STATE: { name: "Update UI State", + tagline: "Update {{path}} to {{value}}", icon: "", description: "Update your User Interface with some data.", - type: "CLIENT", + environment: "CLIENT", + params: { + path: "string", + value: "string", + }, }, NAVIGATE: { name: "Navigate", icon: "ri-navigation-line", description: "Navigate to another page.", - type: "CLIENT" + environment: "CLIENT", + params: { + url: "string", + }, }, SAVE_RECORD: { name: "Save Record", icon: "ri-save-3-fill", description: "Save a record to your database.", - type: "SERVER", + environment: "SERVER", + params: { + model: "string", + }, }, DELETE_RECORD: { description: "Delete a record from your database.", icon: "ri-delete-bin-line", name: "Delete Record", - type: "SERVER", + environment: "SERVER", + params: { + record: "string", + }, }, FIND_RECORD: { description: "Delete a record from your database.", icon: "ri-delete-bin-line", name: "Find Record", - type: "SERVER", + environment: "SERVER", + params: { + record: "string", + }, }, CREATE_USER: { description: "Create a new user.", icon: "ri-user-add-fill", name: "Create User", - type: "SERVER", + environment: "SERVER", + params: { + name: "string", + password: "password", + accessLevel: "accessLevel", + }, }, SEND_EMAIL: { description: "Send an email.", + tagline: "Send email to {{to}}", icon: "ri-mail-open-fill", name: "Send Email", - type: "SERVER", - } -}; + environment: "SERVER", + params: { + to: "string", + from: "string", + subject: "string", + text: "string", + }, + }, +} -const TRIGGERS = { +const TRIGGER = { SAVE_RECORD: { name: "Record Saved", icon: "ri-delete-bin-line", + tagline: "Record is added to {{model}}", description: "Save a record to your database.", - type: "SERVER", + environment: "SERVER", + params: { + model: "model", + }, }, CLICK: { name: "Click", icon: "ri-cursor-line", - description: "Trigger when you click on an element in the UI." + description: "Trigger when you click on an element in the UI.", }, LOAD: { name: "Load", icon: "ri-loader-line", - description: "Trigger an element has finished loading." + description: "Trigger an element has finished loading.", }, INPUT: { name: "Input", icon: "ri-text", - description: "Trigger when you type into an input box." + description: "Trigger when you environment into an input box.", }, -}; +} const LOGIC = { FILTER: { name: "Filter", + tagline: "{{key}} {{condition}} {{value}}", icon: "ri-git-branch-line", description: "Filter any workflows which do not meet certain conditions.", - type: "CLIENT" + environment: "CLIENT", + params: { + if: "string", + }, }, DELAY: { name: "Delay", icon: "ri-git-branch-line", description: "Delay the workflow until an amount of time has passed.", - type: "CLIENT" + environment: "CLIENT", }, } export default { - ACTIONS, - TRIGGERS, - LOGIC -} \ No newline at end of file + ACTION, + TRIGGER, + LOGIC, +} diff --git a/packages/builder/src/pages/[application]/workflow/WorkflowPanel/index.js b/packages/builder/src/pages/[application]/workflow/WorkflowPanel/index.js index dea50a6d41..35fec385a7 100644 --- a/packages/builder/src/pages/[application]/workflow/WorkflowPanel/index.js +++ b/packages/builder/src/pages/[application]/workflow/WorkflowPanel/index.js @@ -1,3 +1,3 @@ -export { default as WorkflowPanel } from "./WorkflowPanel.svelte"; -export { default as BlockList } from "./BlockList/BlockList.svelte"; -export { default as WorkflowList } from "./WorkflowList/WorkflowList.svelte"; \ No newline at end of file +export { default as WorkflowPanel } from "./WorkflowPanel.svelte" +export { default as BlockList } from "./BlockList/BlockList.svelte" +export { default as WorkflowList } from "./WorkflowList/WorkflowList.svelte" diff --git a/packages/builder/src/pages/[application]/workflow/_layout.svelte b/packages/builder/src/pages/[application]/workflow/_layout.svelte index 54aa07717f..f1cd9e76dd 100644 --- a/packages/builder/src/pages/[application]/workflow/_layout.svelte +++ b/packages/builder/src/pages/[application]/workflow/_layout.svelte @@ -24,6 +24,7 @@ .nav { padding: 20px; + height: 100%; } .root { diff --git a/packages/builder/src/pages/[application]/workflow/index.svelte b/packages/builder/src/pages/[application]/workflow/index.svelte index 817aa67552..88f65b0b18 100644 --- a/packages/builder/src/pages/[application]/workflow/index.svelte +++ b/packages/builder/src/pages/[application]/workflow/index.svelte @@ -1,5 +1,5 @@ - - \ No newline at end of file + diff --git a/packages/client/src/api/index.js b/packages/client/src/api/index.js index ef6c6d06b9..00f8405cfb 100644 --- a/packages/client/src/api/index.js +++ b/packages/client/src/api/index.js @@ -2,8 +2,7 @@ import { loadRecord } from "./loadRecord" import { listRecords } from "./listRecords" import { authenticate } from "./authenticate" import { saveRecord } from "./saveRecord" -import { triggerWorkflow } from "./workflow"; - +import { triggerWorkflow } from "./workflow" export const createApi = ({ rootPath = "", setState, getState }) => { const apiCall = method => async ({ url, body }) => { @@ -16,7 +15,6 @@ export const createApi = ({ rootPath = "", setState, getState }) => { credentials: "same-origin", }) - switch (response.status) { case 200: return response.json() @@ -27,7 +25,7 @@ export const createApi = ({ rootPath = "", setState, getState }) => { case 403: return error(`${url} Forbidden`) default: - if (response.status >= 200 && response.status < 400) { + if (response.status >= 200 && response.status < 400) { return response.json() } @@ -66,6 +64,6 @@ export const createApi = ({ rootPath = "", setState, getState }) => { listRecords: listRecords(apiOpts), authenticate: authenticate(apiOpts), saveRecord: saveRecord(apiOpts), - triggerWorkflow: triggerWorkflow(apiOpts) + triggerWorkflow: triggerWorkflow(apiOpts), } } diff --git a/packages/client/src/api/workflow/index.js b/packages/client/src/api/workflow/index.js index f9aa3403b3..2e3c025adb 100644 --- a/packages/client/src/api/workflow/index.js +++ b/packages/client/src/api/workflow/index.js @@ -1,15 +1,13 @@ -import Orchestrator, { clientStrategy } from "./orchestrator"; - +import Orchestrator, { clientStrategy } from "./orchestrator" export const triggerWorkflow = api => ({ workflow }) => { const workflowOrchestrator = new Orchestrator( api, "inst_60dd510_700f7dc06735403e81d5af91072d7241" - ); + ) workflowOrchestrator.strategy = clientStrategy - workflowOrchestrator.execute(workflow); + workflowOrchestrator.execute(workflow) // hit the API and get the workflow data back - -} \ No newline at end of file +} diff --git a/packages/client/src/api/workflow/orchestrator.js b/packages/client/src/api/workflow/orchestrator.js index 46b12f89a2..afa92d007e 100644 --- a/packages/client/src/api/workflow/orchestrator.js +++ b/packages/client/src/api/workflow/orchestrator.js @@ -1,11 +1,11 @@ -import get from "lodash/fp/get"; +import get from "lodash/fp/get" /** * The workflow orhestrator is a class responsible for executing workflows. - * It relies on the strategy pattern, which allows composable behaviour to be + * It relies on the strategy pattern, which allows composable behaviour to be * passed into its execute() function. This allows custom execution behaviour based * on where the orchestrator is run. - * + * */ export default class Orchestrator { constructor(api, instanceId) { @@ -18,13 +18,13 @@ export default class Orchestrator { } async execute(workflowId) { - const EXECUTE_WORKFLOW_URL = `/api/${this.instanceId}/workflows/${workflowId}`; - const workflow = await this.api.get({ url: EXECUTE_WORKFLOW_URL }) + const EXECUTE_WORKFLOW_URL = `/api/${this.instanceId}/workflows/${workflowId}` + const workflow = await this.api.get({ url: EXECUTE_WORKFLOW_URL }) this._strategy.run({ workflow: workflow.definition, api: this.api, - instanceId: this.instanceId - }); + instanceId: this.instanceId, + }) } } @@ -32,76 +32,76 @@ export default class Orchestrator { export const clientStrategy = { context: {}, bindContextArgs: function(args, api) { - const mappedArgs = { ...args }; + const mappedArgs = { ...args } console.log("original args", args) // bind the workflow action args to the workflow context, if required for (let arg in args) { - const argValue = args[arg]; + const argValue = args[arg] // Means that it's bound to state or workflow context if (argValue.startsWith("$")) { // if value is bound to workflow context. if (argValue.startsWith("$context")) { - const path = argValue.replace("$context.", ""); + const path = argValue.replace("$context.", "") // pass in the value from context - mappedArgs[arg] = get(path, this.context); + mappedArgs[arg] = get(path, this.context) } // if the value is bound to state if (argValue.startsWith("$state")) { - const path = argValue.replace("$state.", ""); + const path = argValue.replace("$state.", "") // pass in the value from state // TODO: not working - mappedArgs[arg] = api.getState(path); + mappedArgs[arg] = api.getState(path) } } } - console.log(mappedArgs); + console.log(mappedArgs) - return Object.values(mappedArgs); + return Object.values(mappedArgs) }, run: async function({ workflow, api, instanceId }) { - const block = workflow.next; + const block = workflow.next - console.log("Executing workflow block", block); + console.log("Executing workflow block", block) - if (!block) return; + if (!block) return // This code gets run in the browser - if (block.type === "CLIENT") { - if (block.actionId === "SET_STATE") { - // get props from the workflow context if required - api.setState(...this.bindContextArgs(block.args)) - // update the context with the data - this.context = { - ...this.context, - SET_STATE: block.args - } + if (block.environment === "CLIENT") { + if (block.actionId === "SET_STATE") { + // get props from the workflow context if required + api.setState(...this.bindContextArgs(block.args)) + // update the context with the data + this.context = { + ...this.context, + SET_STATE: block.args, } - }; + } + } // this workflow block gets executed on the server - if (block.type === "SERVER") { + if (block.environment === "SERVER") { const EXECUTE_WORKFLOW_URL = `/api/${instanceId}/workflows/action` - const response = await api.post({ - url: EXECUTE_WORKFLOW_URL, + const response = await api.post({ + url: EXECUTE_WORKFLOW_URL, body: { action: block.actionId, - args: this.bindContextArgs(block.args, api) - } - }); + args: this.bindContextArgs(block.args, api), + }, + }) this.context = { ...this.context, - [block.actionId]: response + [block.actionId]: response, } } console.log("workflowContext", this.context) // TODO: clean this up, don't pass all those args - this.run({ workflow: workflow.next, instanceId, api }); - } -} \ No newline at end of file + this.run({ workflow: workflow.next, instanceId, api }) + }, +} diff --git a/packages/server/src/api/controllers/record.js b/packages/server/src/api/controllers/record.js index c4ac1deba3..c3e1fa940d 100644 --- a/packages/server/src/api/controllers/record.js +++ b/packages/server/src/api/controllers/record.js @@ -5,7 +5,7 @@ const newid = require("../../db/newid") const ajv = new Ajv() exports.save = async function(ctx) { - console.log("THIS INSTANCE", ctx.params.instanceId); + console.log("THIS INSTANCE", ctx.params.instanceId) const db = new CouchDB(ctx.params.instanceId) const record = ctx.request.body record.modelId = ctx.params.modelId diff --git a/packages/server/src/api/controllers/workflow/actions/CUSTOM_JS.js b/packages/server/src/api/controllers/workflow/actions/CUSTOM_JS.js index 77ac39783d..73072f2ac9 100644 --- a/packages/server/src/api/controllers/workflow/actions/CUSTOM_JS.js +++ b/packages/server/src/api/controllers/workflow/actions/CUSTOM_JS.js @@ -1,9 +1,9 @@ -export default async function () { - const response = await fetch("www.google.com"); - console.log(response); - console.log("CUSTOM ACTION"); +export default async function() { + const response = await fetch("www.google.com") + console.log(response) + console.log("CUSTOM ACTION") return { message: "CUSTOM_WORKFLOW_SCRIPT", - response + response, } -} \ No newline at end of file +} diff --git a/packages/server/src/api/controllers/workflow/actions/SAVE_RECORD.js b/packages/server/src/api/controllers/workflow/actions/SAVE_RECORD.js index 05d42bfc11..24225f2287 100644 --- a/packages/server/src/api/controllers/workflow/actions/SAVE_RECORD.js +++ b/packages/server/src/api/controllers/workflow/actions/SAVE_RECORD.js @@ -1,20 +1,20 @@ -const recordController = require("../../record"); +const recordController = require("../../record") module.exports = async function saveRecord(args) { - console.log("SAVING this record", args.record); + console.log("SAVING this record", args.record) const ctx = { params: { instanceId: "inst_60dd510_700f7dc06735403e81d5af91072d7241", }, request: { - body: args.record - } + body: args.record, + }, } - await recordController.save(ctx); + await recordController.save(ctx) return { - record: ctx.body + record: ctx.body, } -} \ No newline at end of file +} diff --git a/packages/server/src/api/controllers/workflow/actions/SEND_EMAIL.js b/packages/server/src/api/controllers/workflow/actions/SEND_EMAIL.js index 072d61932f..ef582781b8 100644 --- a/packages/server/src/api/controllers/workflow/actions/SEND_EMAIL.js +++ b/packages/server/src/api/controllers/workflow/actions/SEND_EMAIL.js @@ -1,27 +1,25 @@ -const sgMail = require('@sendgrid/mail'); +const sgMail = require("@sendgrid/mail") -sgMail.setApiKey(process.env.SENDGRID_API_KEY); +sgMail.setApiKey(process.env.SENDGRID_API_KEY) module.exports = async function sendEmail(args) { - const msg = { to: args.to, from: args.from, subject: args.subject, - text: args.text - }; + text: args.text, + } try { - await sgMail.send(msg); + await sgMail.send(msg) return { success: true, - err + err, } } catch (err) { return { success: false, - err + err, } } - -} \ No newline at end of file +} diff --git a/packages/server/src/api/controllers/workflow/index.js b/packages/server/src/api/controllers/workflow/index.js index ee7c536519..1a4cfa8591 100644 --- a/packages/server/src/api/controllers/workflow/index.js +++ b/packages/server/src/api/controllers/workflow/index.js @@ -28,7 +28,6 @@ exports.create = async function(ctx) { // return // } - workflow.type = "workflow" const response = await db.post(workflow) workflow._rev = response.rev @@ -39,14 +38,14 @@ exports.create = async function(ctx) { workflow: { ...workflow, _rev: response.rev, - _id: response.id - } - }; + _id: response.id, + }, + } } exports.update = async function(ctx) { const db = new CouchDB(ctx.params.instanceId) - const workflow = ctx.request.body; + const workflow = ctx.request.body const response = await db.put(workflow) workflow._rev = response.rev @@ -57,7 +56,7 @@ exports.update = async function(ctx) { workflow: { ...workflow, _rev: response.rev, - _id: response.id + _id: response.id, }, } } @@ -77,15 +76,15 @@ exports.find = async function(ctx) { } exports.executeAction = async function(ctx) { - const workflowAction = require(`./actions/${ctx.request.body.action}`); - const response = await workflowAction(ctx.request.body.args); - ctx.body = response; + const workflowAction = require(`./actions/${ctx.request.body.action}`) + const response = await workflowAction(ctx.request.body.args) + ctx.body = response } exports.fetchActionScript = async function(ctx) { - const workflowAction = require(`./actions/${ctx.action}`); - console.log(workflowAction); - ctx.body = workflowAction; + const workflowAction = require(`./actions/${ctx.action}`) + console.log(workflowAction) + ctx.body = workflowAction } exports.destroy = async function(ctx) { diff --git a/packages/server/src/app.js b/packages/server/src/app.js index f947738567..57fb037626 100644 --- a/packages/server/src/app.js +++ b/packages/server/src/app.js @@ -4,7 +4,7 @@ const logger = require("koa-pino-logger") const http = require("http") const api = require("./api") const env = require("./environment") -const eventPublisher = require("./events"); +const eventPublisher = require("./events") const app = new Koa() @@ -20,7 +20,7 @@ app.use( }) ) -app.context.publisher = eventPublisher; +app.context.publisher = eventPublisher // api routes app.use(api.routes()) diff --git a/packages/server/src/events/index.js b/packages/server/src/events/index.js index 14e4e052e1..7d54c4cd95 100644 --- a/packages/server/src/events/index.js +++ b/packages/server/src/events/index.js @@ -1,3 +1,3 @@ -const EventEmitter = require("events").EventEmitter; +const EventEmitter = require("events").EventEmitter -module.exports = new EventEmitter(); \ No newline at end of file +module.exports = new EventEmitter() diff --git a/packages/server/src/schemas/index.js b/packages/server/src/schemas/index.js index 23a839bf97..63a6514043 100644 --- a/packages/server/src/schemas/index.js +++ b/packages/server/src/schemas/index.js @@ -2,37 +2,38 @@ const WORKFLOW_SCHEMA = { properties: { type: "workflow", pageId: { - type: "string" + type: "string", }, screenId: { - type: "string" + type: "string", }, live: { - type: "boolean" + type: "boolean", }, uiTree: { - type: "object" + type: "object", }, definition: { type: "object", properties: { triggers: { type: "array" }, - next: { + next: { type: "object", properties: { + environment: { environment: "string" }, type: { type: "string" }, actionId: { type: "string" }, args: { type: "object" }, conditions: { type: "array" }, errorHandling: { type: "object" }, - next: { type: "object" } - } + next: { type: "object" }, + }, }, - } - } - } -}; + }, + }, + }, +} module.exports = { - WORKFLOW_SCHEMA -}; \ No newline at end of file + WORKFLOW_SCHEMA, +} diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock index 763e28134e..3fc1f15622 100644 --- a/packages/server/yarn.lock +++ b/packages/server/yarn.lock @@ -194,20 +194,6 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" -"@budibase/client@^0.0.32": - version "0.0.32" - resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.0.32.tgz#76d9f147563a0bf939eae7f32ce75b2a527ba496" - integrity sha512-jmCCLn0CUoQbL6h623S5IqK6+GYLqX3WzUTZInSb1SCBOM3pI0eLP5HwTR6s7r42SfD0v9jTWRdyTnHiElNj8A== - dependencies: - "@nx-js/compiler-util" "^2.0.0" - bcryptjs "^2.4.3" - deep-equal "^2.0.1" - lodash "^4.17.15" - lunr "^2.3.5" - regexparam "^1.3.0" - shortid "^2.2.8" - svelte "^3.9.2" - "@budibase/core@^0.0.32": version "0.0.32" resolved "https://registry.yarnpkg.com/@budibase/core/-/core-0.0.32.tgz#c5d9ab869c5e9596a1ac337aaf041e795b1cc7fa" @@ -863,11 +849,6 @@ array-equal@^1.0.0: resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= -array-filter@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" - integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= - array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" @@ -940,13 +921,6 @@ atomic-sleep@^1.0.0: resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== -available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" - integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ== - dependencies: - array-filter "^1.0.0" - aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -1669,26 +1643,6 @@ decompress-response@^3.3.0: dependencies: mimic-response "^1.0.0" -deep-equal@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.3.tgz#cad1c15277ad78a5c01c49c2dee0f54de8a6a7b0" - integrity sha512-Spqdl4H+ky45I9ByyJtXteOm9CaIrPmnIPmOhrkKGNYWeDgCvJ8jNYVCTjChxW4FqGuZnLHADc8EKRMX6+CgvA== - dependencies: - es-abstract "^1.17.5" - es-get-iterator "^1.1.0" - is-arguments "^1.0.4" - is-date-object "^1.0.2" - is-regex "^1.0.5" - isarray "^2.0.5" - object-is "^1.1.2" - object-keys "^1.1.1" - object.assign "^4.1.0" - regexp.prototype.flags "^1.3.0" - side-channel "^1.0.2" - which-boxed-primitive "^1.0.1" - which-collection "^1.0.1" - which-typed-array "^1.1.2" - deep-equal@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" @@ -2047,7 +2001,7 @@ error-inject@^1.0.0: resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37" integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc= -es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstract@^1.17.5: +es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5: version "1.17.5" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg== @@ -2064,19 +2018,6 @@ es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstrac string.prototype.trimleft "^2.1.1" string.prototype.trimright "^2.1.1" -es-get-iterator@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.0.tgz#bb98ad9d6d63b31aacdc8f89d5d0ee57bcb5b4c8" - integrity sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ== - dependencies: - es-abstract "^1.17.4" - has-symbols "^1.0.1" - is-arguments "^1.0.4" - is-map "^2.0.1" - is-set "^2.0.1" - is-string "^1.0.5" - isarray "^2.0.5" - es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -3069,21 +3010,11 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-arguments@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" - integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== - is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= -is-bigint@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.0.tgz#73da8c33208d00f130e9b5e15d23eac9215601c4" - integrity sha512-t5mGUXC/xRheCK431ylNiSkGGpBp8bHENBcENTkDT6ppwPzEVxNGZRvgvmOEfbWkFhA7D2GEuE2mmQTr78sl2g== - is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -3091,11 +3022,6 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-boolean-object@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.1.tgz#10edc0900dd127697a92f6f9807c7617d68ac48e" - integrity sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ== - is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -3132,7 +3058,7 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-date-object@^1.0.1, is-date-object@^1.0.2: +is-date-object@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== @@ -3207,21 +3133,11 @@ is-installed-globally@^0.3.1: global-dirs "^2.0.1" is-path-inside "^3.0.1" -is-map@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1" - integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw== - is-npm@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d" integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig== -is-number-object@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" - integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== - is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -3258,21 +3174,11 @@ is-regex@^1.0.5: dependencies: has "^1.0.3" -is-set@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43" - integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA== - is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= -is-string@^1.0.4, is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== - is-symbol@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" @@ -3289,31 +3195,11 @@ is-type-of@^1.0.0: is-class-hotfix "~0.0.6" isstream "~0.1.2" -is-typed-array@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.3.tgz#a4ff5a5e672e1a55f99c7f54e59597af5c1df04d" - integrity sha512-BSYUBOK/HJibQ30wWkWold5txYwMUXQct9YHAQJr8fSwvZoiglcqB0pd7vEN23+Tsi9IUEjztdOSzl4qLVYGTQ== - dependencies: - available-typed-arrays "^1.0.0" - es-abstract "^1.17.4" - foreach "^2.0.5" - has-symbols "^1.0.1" - is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= -is-weakmap@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" - integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== - -is-weakset@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.1.tgz#e9a0af88dbd751589f5e50d80f4c98b780884f83" - integrity sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw== - is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -3339,11 +3225,6 @@ isarray@1.0.0, isarray@~1.0.0: resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - isbinaryfile@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.6.tgz#edcb62b224e2b4710830b67498c8e4e5a4d2610b" @@ -4751,14 +4632,6 @@ object-inspect@^1.7.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== -object-is@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.2.tgz#c5d2e87ff9e119f78b7a088441519e2eec1573b6" - integrity sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.0.6, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -5480,19 +5353,6 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp.prototype.flags@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" - integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -regexparam@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/regexparam/-/regexparam-1.3.0.tgz#2fe42c93e32a40eff6235d635e0ffa344b92965f" - integrity sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g== - regexpp@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" @@ -5821,14 +5681,6 @@ shortid@^2.2.8: dependencies: nanoid "^2.1.0" -side-channel@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.2.tgz#df5d1abadb4e4bf4af1cd8852bf132d2f7876947" - integrity sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA== - dependencies: - es-abstract "^1.17.0-next.1" - object-inspect "^1.7.0" - signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" @@ -6237,11 +6089,6 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -svelte@^3.9.2: - version "3.22.3" - resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.22.3.tgz#6af3bdcfea44c2fadbf17a32c479f49bdf1aba4b" - integrity sha512-DumSy5eWPFPlMUGf3+eHyFSkt5yLqyAmMdCuXOE4qc5GtFyLxwTAGKZmgKmW2jmbpTTeFQ/fSQfDBQbl9Eo7yw== - symbol-tree@^3.2.2: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" @@ -6722,44 +6569,11 @@ whatwg-url@^7.0.0: tr46 "^1.0.1" webidl-conversions "^4.0.2" -which-boxed-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.1.tgz#cbe8f838ebe91ba2471bb69e9edbda67ab5a5ec1" - integrity sha512-7BT4TwISdDGBgaemWU0N0OU7FeAEJ9Oo2P1PHRm/FCWoEi2VLWC9b6xvxAA3C/NMpxg3HXVgi0sMmGbNUbNepQ== - dependencies: - is-bigint "^1.0.0" - is-boolean-object "^1.0.0" - is-number-object "^1.0.3" - is-string "^1.0.4" - is-symbol "^1.0.2" - -which-collection@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" - integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== - dependencies: - is-map "^2.0.1" - is-set "^2.0.1" - is-weakmap "^2.0.1" - is-weakset "^2.0.1" - which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which-typed-array@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.2.tgz#e5f98e56bda93e3dac196b01d47c1156679c00b2" - integrity sha512-KT6okrd1tE6JdZAy3o2VhMoYPh3+J6EMZLyrxBQsZflI1QCZIxMrIYLkosd8Twf+YfknVIHmYQPgJt238p8dnQ== - dependencies: - available-typed-arrays "^1.0.2" - es-abstract "^1.17.5" - foreach "^2.0.5" - function-bind "^1.1.1" - has-symbols "^1.0.1" - is-typed-array "^1.1.3" - which@^1.2.9, which@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"