🔒 Use isolated-vm
This commit is contained in:
@ -49,21 +49,14 @@ const nextConfig = {
|
|||||||
},
|
},
|
||||||
experimental: {
|
experimental: {
|
||||||
outputFileTracingRoot: join(__dirname, '../../'),
|
outputFileTracingRoot: join(__dirname, '../../'),
|
||||||
|
serverComponentsExternalPackages: ['isolated-vm'],
|
||||||
},
|
},
|
||||||
webpack: (config, { nextRuntime }) => {
|
webpack: (config, { isServer }) => {
|
||||||
if (nextRuntime === 'nodejs') return config
|
if (isServer) return config
|
||||||
|
|
||||||
if (nextRuntime === 'edge') {
|
|
||||||
config.resolve.alias['minio'] = false
|
|
||||||
config.resolve.alias['got'] = false
|
|
||||||
config.resolve.alias['qrcode'] = false
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
// These packages are imports from the integrations definition files that can be ignored for the client.
|
|
||||||
config.resolve.alias['minio'] = false
|
config.resolve.alias['minio'] = false
|
||||||
config.resolve.alias['got'] = false
|
|
||||||
config.resolve.alias['openai'] = false
|
|
||||||
config.resolve.alias['qrcode'] = false
|
config.resolve.alias['qrcode'] = false
|
||||||
|
config.resolve.alias['isolated-vm'] = false
|
||||||
return config
|
return config
|
||||||
},
|
},
|
||||||
headers: async () => {
|
headers: async () => {
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
"format:check": "prettier --check ./src --ignore-path ../../.prettierignore"
|
"format:check": "prettier --check ./src --ignore-path ../../.prettierignore"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typebot.io/theme": "workspace:*",
|
|
||||||
"@braintree/sanitize-url": "7.0.1",
|
"@braintree/sanitize-url": "7.0.1",
|
||||||
"@chakra-ui/anatomy": "2.1.1",
|
"@chakra-ui/anatomy": "2.1.1",
|
||||||
"@chakra-ui/react": "2.7.1",
|
"@chakra-ui/react": "2.7.1",
|
||||||
@ -45,6 +44,7 @@
|
|||||||
"@typebot.io/env": "workspace:*",
|
"@typebot.io/env": "workspace:*",
|
||||||
"@typebot.io/js": "workspace:*",
|
"@typebot.io/js": "workspace:*",
|
||||||
"@typebot.io/nextjs": "workspace:*",
|
"@typebot.io/nextjs": "workspace:*",
|
||||||
|
"@typebot.io/theme": "workspace:*",
|
||||||
"@udecode/cn": "29.0.1",
|
"@udecode/cn": "29.0.1",
|
||||||
"@udecode/plate-basic-marks": "30.5.3",
|
"@udecode/plate-basic-marks": "30.5.3",
|
||||||
"@udecode/plate-common": "30.4.5",
|
"@udecode/plate-common": "30.4.5",
|
||||||
@ -68,9 +68,10 @@
|
|||||||
"framer-motion": "10.3.0",
|
"framer-motion": "10.3.0",
|
||||||
"google-auth-library": "8.9.0",
|
"google-auth-library": "8.9.0",
|
||||||
"google-spreadsheet": "4.1.1",
|
"google-spreadsheet": "4.1.1",
|
||||||
"ky": "1.2.3",
|
|
||||||
"immer": "10.0.2",
|
"immer": "10.0.2",
|
||||||
|
"isolated-vm": "4.7.2",
|
||||||
"jsonwebtoken": "9.0.1",
|
"jsonwebtoken": "9.0.1",
|
||||||
|
"ky": "1.2.3",
|
||||||
"libphonenumber-js": "1.10.37",
|
"libphonenumber-js": "1.10.37",
|
||||||
"micro": "10.0.1",
|
"micro": "10.0.1",
|
||||||
"micro-cors": "0.1.1",
|
"micro-cors": "0.1.1",
|
||||||
@ -123,13 +124,13 @@
|
|||||||
"@types/qs": "6.9.7",
|
"@types/qs": "6.9.7",
|
||||||
"@types/react": "18.2.15",
|
"@types/react": "18.2.15",
|
||||||
"@types/tinycolor2": "1.4.3",
|
"@types/tinycolor2": "1.4.3",
|
||||||
|
"dotenv": "16.4.5",
|
||||||
"dotenv-cli": "7.4.1",
|
"dotenv-cli": "7.4.1",
|
||||||
"eslint": "8.44.0",
|
"eslint": "8.44.0",
|
||||||
"eslint-config-custom": "workspace:*",
|
"eslint-config-custom": "workspace:*",
|
||||||
"next-runtime-env": "1.6.2",
|
"next-runtime-env": "1.6.2",
|
||||||
"superjson": "1.12.4",
|
"superjson": "1.12.4",
|
||||||
"typescript": "5.4.5",
|
"typescript": "5.4.5",
|
||||||
"zod": "3.22.4",
|
"zod": "3.22.4"
|
||||||
"dotenv": "16.4.5"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,11 @@ As you can see, the code block expects the body of the Javascript function. You
|
|||||||
|
|
||||||
If you'd like to set variables directly in this code block, you can use the [`setVariable` function](../logic/script#setvariable-function).
|
If you'd like to set variables directly in this code block, you can use the [`setVariable` function](../logic/script#setvariable-function).
|
||||||
|
|
||||||
|
<Warning>
|
||||||
|
A function is executed on the server so it comes with [some limitations listed
|
||||||
|
here](../logic/script#limitations-on-scripts-executed-on-server).
|
||||||
|
</Warning>
|
||||||
|
|
||||||
## Ask assistant
|
## Ask assistant
|
||||||
|
|
||||||
This action allows you to talk with your [OpenAI assistant](https://platform.openai.com/assistants). All you have to do is to provide its ID.
|
This action allows you to talk with your [OpenAI assistant](https://platform.openai.com/assistants). All you have to do is to provide its ID.
|
||||||
|
@ -22,7 +22,7 @@ You need to write `console.log({{My variable}})` instead of `console.log("{{My v
|
|||||||
|
|
||||||
If you want to set a variable value with Javascript, the [Set variable block](./set-variable) is more appropriate for most cases.
|
If you want to set a variable value with Javascript, the [Set variable block](./set-variable) is more appropriate for most cases.
|
||||||
|
|
||||||
However, if you'd like to set variables with the script blocks, you can use the `setVariable` function in your script:
|
However, if you'd like to set variables in a Script block, you can use the `setVariable` function in your script:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
if({{My variable}} === 'foo') {
|
if({{My variable}} === 'foo') {
|
||||||
@ -34,6 +34,37 @@ if({{My variable}} === 'foo') {
|
|||||||
|
|
||||||
The `setVariable` function is only available in script executed on the server, so it won't work if the `Execute on client?` is checked.
|
The `setVariable` function is only available in script executed on the server, so it won't work if the `Execute on client?` is checked.
|
||||||
|
|
||||||
|
## Limitations on scripts executed on server
|
||||||
|
|
||||||
|
Because the script is executed on a isolated and secured environment, there are some limitations.
|
||||||
|
|
||||||
|
- Global functions like `console.log`, `setTimeout`, `setInterval`, etc. are not available
|
||||||
|
- The `fetch` function behavior is slightly different from the native `fetch` function. You just have to skip the `await response.text()` or `await response.json()` part.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// ❌ This throws an error
|
||||||
|
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1')
|
||||||
|
const data = await response.text()
|
||||||
|
|
||||||
|
// ✅ This works
|
||||||
|
const data = await fetch('https://jsonplaceholder.typicode.com/todos/1')
|
||||||
|
```
|
||||||
|
|
||||||
|
`response` will always be a `string` even if the the request returns a JSON object. If you know that the response is a JSON object, you can parse it using `JSON.parse(response)`.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// ❌ This throws an error
|
||||||
|
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1')
|
||||||
|
const data = await response.json()
|
||||||
|
|
||||||
|
// ✅ This works
|
||||||
|
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1')
|
||||||
|
const data = JSON.parse(response)
|
||||||
|
```
|
||||||
|
|
||||||
|
- You can't use `import` or `require` to import external libraries
|
||||||
|
- You don't have access to browser APIs like `window`, `document`, `localStorage`, etc. If you need to use browser APIs, you should check the `Execute on client?` option so that the script is executed on the user's browser.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
### Reload page
|
### Reload page
|
||||||
|
@ -50,21 +50,14 @@ const nextConfig = {
|
|||||||
output: 'standalone',
|
output: 'standalone',
|
||||||
experimental: {
|
experimental: {
|
||||||
outputFileTracingRoot: join(__dirname, '../../'),
|
outputFileTracingRoot: join(__dirname, '../../'),
|
||||||
|
serverComponentsExternalPackages: ['isolated-vm'],
|
||||||
},
|
},
|
||||||
webpack: (config, { nextRuntime }) => {
|
webpack: (config, { isServer }) => {
|
||||||
if (nextRuntime === 'nodejs') return config
|
if (isServer) return config
|
||||||
|
|
||||||
if (nextRuntime === 'edge') {
|
|
||||||
config.resolve.alias['minio'] = false
|
|
||||||
config.resolve.alias['got'] = false
|
|
||||||
config.resolve.alias['qrcode'] = false
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
// These packages are imports from the integrations definition files that can be ignored for the client.
|
|
||||||
config.resolve.alias['minio'] = false
|
config.resolve.alias['minio'] = false
|
||||||
config.resolve.alias['got'] = false
|
|
||||||
config.resolve.alias['openai'] = false
|
|
||||||
config.resolve.alias['qrcode'] = false
|
config.resolve.alias['qrcode'] = false
|
||||||
|
config.resolve.alias['isolated-vm'] = false
|
||||||
return config
|
return config
|
||||||
},
|
},
|
||||||
async redirects() {
|
async redirects() {
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
"cors": "2.8.5",
|
"cors": "2.8.5",
|
||||||
"google-spreadsheet": "4.1.1",
|
"google-spreadsheet": "4.1.1",
|
||||||
"got": "12.6.0",
|
"got": "12.6.0",
|
||||||
|
"isolated-vm": "4.7.2",
|
||||||
"ky": "1.2.3",
|
"ky": "1.2.3",
|
||||||
"next": "14.1.0",
|
"next": "14.1.0",
|
||||||
"nextjs-cors": "2.1.2",
|
"nextjs-cors": "2.1.2",
|
||||||
@ -37,7 +38,6 @@
|
|||||||
"stripe": "12.13.0"
|
"stripe": "12.13.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"dotenv": "16.4.5",
|
|
||||||
"@faire/mjml-react": "3.3.0",
|
"@faire/mjml-react": "3.3.0",
|
||||||
"@paralleldrive/cuid2": "2.2.1",
|
"@paralleldrive/cuid2": "2.2.1",
|
||||||
"@playwright/test": "1.43.1",
|
"@playwright/test": "1.43.1",
|
||||||
@ -46,6 +46,8 @@
|
|||||||
"@typebot.io/forge": "workspace:*",
|
"@typebot.io/forge": "workspace:*",
|
||||||
"@typebot.io/forge-repository": "workspace:*",
|
"@typebot.io/forge-repository": "workspace:*",
|
||||||
"@typebot.io/lib": "workspace:*",
|
"@typebot.io/lib": "workspace:*",
|
||||||
|
"@typebot.io/playwright": "workspace:*",
|
||||||
|
"@typebot.io/results": "workspace:*",
|
||||||
"@typebot.io/schemas": "workspace:*",
|
"@typebot.io/schemas": "workspace:*",
|
||||||
"@typebot.io/tsconfig": "workspace:*",
|
"@typebot.io/tsconfig": "workspace:*",
|
||||||
"@typebot.io/variables": "workspace:*",
|
"@typebot.io/variables": "workspace:*",
|
||||||
@ -55,8 +57,8 @@
|
|||||||
"@types/papaparse": "5.3.7",
|
"@types/papaparse": "5.3.7",
|
||||||
"@types/qs": "6.9.7",
|
"@types/qs": "6.9.7",
|
||||||
"@types/react": "18.2.15",
|
"@types/react": "18.2.15",
|
||||||
"dotenv-cli": "7.4.1",
|
|
||||||
"dotenv": "16.4.5",
|
"dotenv": "16.4.5",
|
||||||
|
"dotenv-cli": "7.4.1",
|
||||||
"eslint": "8.44.0",
|
"eslint": "8.44.0",
|
||||||
"eslint-config-custom": "workspace:*",
|
"eslint-config-custom": "workspace:*",
|
||||||
"google-auth-library": "8.9.0",
|
"google-auth-library": "8.9.0",
|
||||||
@ -64,8 +66,6 @@
|
|||||||
"papaparse": "5.4.1",
|
"papaparse": "5.4.1",
|
||||||
"superjson": "1.12.4",
|
"superjson": "1.12.4",
|
||||||
"typescript": "5.4.5",
|
"typescript": "5.4.5",
|
||||||
"zod": "3.22.4",
|
"zod": "3.22.4"
|
||||||
"@typebot.io/playwright": "workspace:*",
|
|
||||||
"@typebot.io/results": "workspace:*"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import { SessionState } from '@typebot.io/schemas/features/chat/sessionState'
|
|||||||
import { ExecuteIntegrationResponse } from '../../../types'
|
import { ExecuteIntegrationResponse } from '../../../types'
|
||||||
import { parseVariables } from '@typebot.io/variables/parseVariables'
|
import { parseVariables } from '@typebot.io/variables/parseVariables'
|
||||||
import { updateVariablesInSession } from '@typebot.io/variables/updateVariablesInSession'
|
import { updateVariablesInSession } from '@typebot.io/variables/updateVariablesInSession'
|
||||||
import vm from 'vm'
|
import { createHttpReqResponseMappingRunner } from '@typebot.io/variables/codeRunners'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
state: SessionState
|
state: SessionState
|
||||||
@ -50,19 +50,21 @@ export const resumeWebhookExecution = ({
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let run: (varMapping: string) => unknown
|
||||||
|
if (block.options?.responseVariableMapping) {
|
||||||
|
run = createHttpReqResponseMappingRunner(response)
|
||||||
|
}
|
||||||
const newVariables = block.options?.responseVariableMapping?.reduce<
|
const newVariables = block.options?.responseVariableMapping?.reduce<
|
||||||
VariableWithUnknowValue[]
|
VariableWithUnknowValue[]
|
||||||
>((newVariables, varMapping) => {
|
>((newVariables, varMapping) => {
|
||||||
if (!varMapping?.bodyPath || !varMapping.variableId) return newVariables
|
if (!varMapping?.bodyPath || !varMapping.variableId || !run)
|
||||||
|
return newVariables
|
||||||
const existingVariable = typebot.variables.find(byId(varMapping.variableId))
|
const existingVariable = typebot.variables.find(byId(varMapping.variableId))
|
||||||
if (!existingVariable) return newVariables
|
if (!existingVariable) return newVariables
|
||||||
const sandbox = vm.createContext({
|
|
||||||
data: response,
|
|
||||||
})
|
|
||||||
try {
|
try {
|
||||||
const value: unknown = vm.runInContext(
|
const value: unknown = run(
|
||||||
`data.${parseVariables(typebot.variables)(varMapping?.bodyPath)}`,
|
parseVariables(typebot.variables)(varMapping?.bodyPath)
|
||||||
sandbox
|
|
||||||
)
|
)
|
||||||
return [...newVariables, { ...existingVariable, value }]
|
return [...newVariables, { ...existingVariable, value }]
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -8,7 +8,6 @@ import {
|
|||||||
import { byId, isEmpty } from '@typebot.io/lib'
|
import { byId, isEmpty } from '@typebot.io/lib'
|
||||||
import { ExecuteLogicResponse } from '../../../types'
|
import { ExecuteLogicResponse } from '../../../types'
|
||||||
import { parseScriptToExecuteClientSideAction } from '../script/executeScript'
|
import { parseScriptToExecuteClientSideAction } from '../script/executeScript'
|
||||||
import { parseGuessedValueType } from '@typebot.io/variables/parseGuessedValueType'
|
|
||||||
import { parseVariables } from '@typebot.io/variables/parseVariables'
|
import { parseVariables } from '@typebot.io/variables/parseVariables'
|
||||||
import { updateVariablesInSession } from '@typebot.io/variables/updateVariablesInSession'
|
import { updateVariablesInSession } from '@typebot.io/variables/updateVariablesInSession'
|
||||||
import { createId } from '@paralleldrive/cuid2'
|
import { createId } from '@paralleldrive/cuid2'
|
||||||
@ -19,7 +18,7 @@ import {
|
|||||||
} from '@typebot.io/logic/computeResultTranscript'
|
} from '@typebot.io/logic/computeResultTranscript'
|
||||||
import prisma from '@typebot.io/lib/prisma'
|
import prisma from '@typebot.io/lib/prisma'
|
||||||
import { sessionOnlySetVariableOptions } from '@typebot.io/schemas/features/blocks/logic/setVariable/constants'
|
import { sessionOnlySetVariableOptions } from '@typebot.io/schemas/features/blocks/logic/setVariable/constants'
|
||||||
import vm from 'vm'
|
import { createCodeRunner } from '@typebot.io/variables/codeRunners'
|
||||||
|
|
||||||
export const executeSetVariable = async (
|
export const executeSetVariable = async (
|
||||||
state: SessionState,
|
state: SessionState,
|
||||||
@ -97,17 +96,11 @@ const evaluateSetVariableExpression =
|
|||||||
if (isSingleVariable) return parseVariables(variables)(str)
|
if (isSingleVariable) return parseVariables(variables)(str)
|
||||||
// To avoid octal number evaluation
|
// To avoid octal number evaluation
|
||||||
if (!isNaN(str as unknown as number) && /0[^.].+/.test(str)) return str
|
if (!isNaN(str as unknown as number) && /0[^.].+/.test(str)) return str
|
||||||
const evaluating = parseVariables(variables, { fieldToParse: 'id' })(
|
|
||||||
`(function() {${str.includes('return ') ? str : 'return ' + str}})()`
|
|
||||||
)
|
|
||||||
try {
|
try {
|
||||||
const sandbox = vm.createContext({
|
const body = parseVariables(variables, { fieldToParse: 'id' })(str)
|
||||||
...Object.fromEntries(
|
return createCodeRunner({ variables })(
|
||||||
variables.map((v) => [v.id, parseGuessedValueType(v.value)])
|
body.includes('return ') ? body : `return ${body}`
|
||||||
),
|
)
|
||||||
fetch,
|
|
||||||
})
|
|
||||||
return vm.runInContext(evaluating, sandbox)
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return parseVariables(variables)(str)
|
return parseVariables(variables)(str)
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,8 @@
|
|||||||
"nodemailer": "6.9.8",
|
"nodemailer": "6.9.8",
|
||||||
"openai": "4.47.1",
|
"openai": "4.47.1",
|
||||||
"qs": "6.11.2",
|
"qs": "6.11.2",
|
||||||
"stripe": "12.13.0"
|
"stripe": "12.13.0",
|
||||||
|
"isolated-vm": "4.7.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@typebot.io/forge": "workspace:*",
|
"@typebot.io/forge": "workspace:*",
|
||||||
|
55
packages/variables/codeRunners.ts
Normal file
55
packages/variables/codeRunners.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { Variable } from './types'
|
||||||
|
import ivm from 'isolated-vm'
|
||||||
|
import { parseGuessedValueType } from './parseGuessedValueType'
|
||||||
|
|
||||||
|
export const createCodeRunner = ({ variables }: { variables: Variable[] }) => {
|
||||||
|
const isolate = new ivm.Isolate()
|
||||||
|
const context = isolate.createContextSync()
|
||||||
|
const jail = context.global
|
||||||
|
jail.setSync('global', jail.derefInto())
|
||||||
|
variables.forEach((v) => {
|
||||||
|
jail.setSync(v.id, parseTransferrableValue(parseGuessedValueType(v.value)))
|
||||||
|
})
|
||||||
|
return (code: string) =>
|
||||||
|
context.evalClosureSync(
|
||||||
|
`return (function() {
|
||||||
|
return new Function($0)();
|
||||||
|
}())`,
|
||||||
|
[code],
|
||||||
|
{ result: { copy: true }, timeout: 10000 }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createHttpReqResponseMappingRunner = (response: any) => {
|
||||||
|
const isolate = new ivm.Isolate()
|
||||||
|
const context = isolate.createContextSync()
|
||||||
|
const jail = context.global
|
||||||
|
jail.setSync('global', jail.derefInto())
|
||||||
|
jail.setSync('response', new ivm.ExternalCopy(response).copyInto())
|
||||||
|
return (expression: string) => {
|
||||||
|
return context.evalClosureSync(
|
||||||
|
`globalThis.evaluateExpression = function(expression) {
|
||||||
|
try {
|
||||||
|
// Use Function to safely evaluate the expression
|
||||||
|
const func = new Function('statusCode', 'data', 'return (' + expression + ')');
|
||||||
|
return func(response.statusCode, response.data);
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error('Invalid expression: ' + err.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return evaluateExpression.apply(null, arguments);`,
|
||||||
|
[expression],
|
||||||
|
{
|
||||||
|
result: { copy: true },
|
||||||
|
timeout: 10000,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseTransferrableValue = (value: unknown) => {
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
return new ivm.ExternalCopy(value).copyInto()
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
@ -4,9 +4,9 @@ import { parseGuessedValueType } from './parseGuessedValueType'
|
|||||||
import { isDefined } from '@typebot.io/lib'
|
import { isDefined } from '@typebot.io/lib'
|
||||||
import { safeStringify } from '@typebot.io/lib/safeStringify'
|
import { safeStringify } from '@typebot.io/lib/safeStringify'
|
||||||
import { Variable } from './types'
|
import { Variable } from './types'
|
||||||
import vm from 'vm'
|
import ivm from 'isolated-vm'
|
||||||
|
|
||||||
const defaultTimeout = 10
|
const defaultTimeout = 10 * 1000
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
variables: Variable[]
|
variables: Variable[]
|
||||||
@ -19,9 +19,9 @@ export const executeFunction = async ({
|
|||||||
body,
|
body,
|
||||||
args: initialArgs,
|
args: initialArgs,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const parsedBody = `(async function() {${parseVariables(variables, {
|
const parsedBody = parseVariables(variables, {
|
||||||
fieldToParse: 'id',
|
fieldToParse: 'id',
|
||||||
})(body)}})()`
|
})(body)
|
||||||
|
|
||||||
const args = (
|
const args = (
|
||||||
extractVariablesFromText(variables)(body).map((variable) => ({
|
extractVariablesFromText(variables)(body).map((variable) => ({
|
||||||
@ -40,21 +40,40 @@ export const executeFunction = async ({
|
|||||||
updatedVariables[key] = value
|
updatedVariables[key] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
const context = vm.createContext({
|
const isolate = new ivm.Isolate()
|
||||||
...Object.fromEntries(args.map(({ id, value }) => [id, value])),
|
const context = isolate.createContextSync()
|
||||||
setVariable,
|
const jail = context.global
|
||||||
fetch,
|
jail.setSync('global', jail.derefInto())
|
||||||
setTimeout,
|
context.evalClosure(
|
||||||
|
'globalThis.setVariable = (...args) => $0.apply(undefined, args, { arguments: { copy: true }, promise: true, result: { copy: true, promise: true } })',
|
||||||
|
[new ivm.Reference(setVariable)]
|
||||||
|
)
|
||||||
|
context.evalClosure(
|
||||||
|
'globalThis.fetch = (...args) => $0.apply(undefined, args, { arguments: { copy: true }, promise: true, result: { copy: true, promise: true } })',
|
||||||
|
[
|
||||||
|
new ivm.Reference(async (...args: any[]) => {
|
||||||
|
// @ts-ignore
|
||||||
|
const response = await fetch(...args)
|
||||||
|
return response.text()
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
args.forEach(({ id, value }) => {
|
||||||
|
jail.setSync(id, value)
|
||||||
})
|
})
|
||||||
|
const run = (code: string) =>
|
||||||
const timeout = new Timeout()
|
context.evalClosure(
|
||||||
|
`return (async function() {
|
||||||
|
const AsyncFunction = async function () {}.constructor;
|
||||||
|
return new AsyncFunction($0)();
|
||||||
|
}())`,
|
||||||
|
[code],
|
||||||
|
{ result: { copy: true, promise: true }, timeout: defaultTimeout }
|
||||||
|
)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const output: unknown = await timeout.wrap(
|
const output = await run(parsedBody)
|
||||||
await vm.runInContext(parsedBody, context),
|
console.log('Output', output)
|
||||||
defaultTimeout * 1000
|
|
||||||
)
|
|
||||||
timeout.clear()
|
|
||||||
return {
|
return {
|
||||||
output: safeStringify(output) ?? '',
|
output: safeStringify(output) ?? '',
|
||||||
newVariables: Object.entries(updatedVariables)
|
newVariables: Object.entries(updatedVariables)
|
||||||
@ -86,33 +105,3 @@ export const executeFunction = async ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Timeout {
|
|
||||||
private ids: NodeJS.Timeout[]
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.ids = []
|
|
||||||
}
|
|
||||||
|
|
||||||
private set = (delay: number) =>
|
|
||||||
new Promise((_, reject) => {
|
|
||||||
const id = setTimeout(() => {
|
|
||||||
reject(`Script ${defaultTimeout}s timeout reached`)
|
|
||||||
this.clear(id)
|
|
||||||
}, delay)
|
|
||||||
this.ids.push(id)
|
|
||||||
})
|
|
||||||
|
|
||||||
wrap = (promise: Promise<any>, delay: number) =>
|
|
||||||
Promise.race([promise, this.set(delay)])
|
|
||||||
|
|
||||||
clear = (...ids: NodeJS.Timeout[]) => {
|
|
||||||
this.ids = this.ids.filter((id) => {
|
|
||||||
if (ids.includes(id)) {
|
|
||||||
clearTimeout(id)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typebot.io/lib": "workspace:*",
|
"@typebot.io/lib": "workspace:*",
|
||||||
"@typebot.io/tsconfig": "workspace:*"
|
"@typebot.io/tsconfig": "workspace:*",
|
||||||
|
"isolated-vm": "4.7.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { safeStringify } from '@typebot.io/lib/safeStringify'
|
import { safeStringify } from '@typebot.io/lib/safeStringify'
|
||||||
import { isDefined, isNotDefined } from '@typebot.io/lib/utils'
|
import { isDefined, isNotDefined } from '@typebot.io/lib/utils'
|
||||||
import { parseGuessedValueType } from './parseGuessedValueType'
|
|
||||||
import { Variable, VariableWithValue } from './types'
|
import { Variable, VariableWithValue } from './types'
|
||||||
import vm from 'vm'
|
import { createCodeRunner } from './codeRunners'
|
||||||
|
|
||||||
export type ParseVariablesOptions = {
|
export type ParseVariablesOptions = {
|
||||||
fieldToParse?: 'value' | 'id'
|
fieldToParse?: 'value' | 'id'
|
||||||
@ -73,18 +72,10 @@ const evaluateInlineCode = (
|
|||||||
code: string,
|
code: string,
|
||||||
{ variables }: { variables: Variable[] }
|
{ variables }: { variables: Variable[] }
|
||||||
) => {
|
) => {
|
||||||
const evaluating = parseVariables(variables, { fieldToParse: 'id' })(
|
|
||||||
`(function() {
|
|
||||||
${code.includes('return ') ? code : 'return ' + code}
|
|
||||||
})()`
|
|
||||||
)
|
|
||||||
try {
|
try {
|
||||||
const sandbox = vm.createContext({
|
return createCodeRunner({ variables })(
|
||||||
...Object.fromEntries(
|
parseVariables(variables, { fieldToParse: 'id' })(code)
|
||||||
variables.map((v) => [v.id, parseGuessedValueType(v.value)])
|
)
|
||||||
),
|
|
||||||
})
|
|
||||||
return vm.runInContext(evaluating, sandbox)
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return parseVariables(variables)(code)
|
return parseVariables(variables)(code)
|
||||||
}
|
}
|
||||||
|
143
pnpm-lock.yaml
generated
143
pnpm-lock.yaml
generated
@ -197,6 +197,9 @@ importers:
|
|||||||
immer:
|
immer:
|
||||||
specifier: 10.0.2
|
specifier: 10.0.2
|
||||||
version: 10.0.2
|
version: 10.0.2
|
||||||
|
isolated-vm:
|
||||||
|
specifier: 4.7.2
|
||||||
|
version: 4.7.2
|
||||||
jsonwebtoken:
|
jsonwebtoken:
|
||||||
specifier: 9.0.1
|
specifier: 9.0.1
|
||||||
version: 9.0.1
|
version: 9.0.1
|
||||||
@ -550,6 +553,9 @@ importers:
|
|||||||
got:
|
got:
|
||||||
specifier: 12.6.0
|
specifier: 12.6.0
|
||||||
version: 12.6.0
|
version: 12.6.0
|
||||||
|
isolated-vm:
|
||||||
|
specifier: 4.7.2
|
||||||
|
version: 4.7.2
|
||||||
ky:
|
ky:
|
||||||
specifier: 1.2.3
|
specifier: 1.2.3
|
||||||
version: 1.2.3
|
version: 1.2.3
|
||||||
@ -744,6 +750,9 @@ importers:
|
|||||||
google-spreadsheet:
|
google-spreadsheet:
|
||||||
specifier: 4.1.1
|
specifier: 4.1.1
|
||||||
version: 4.1.1(google-auth-library@8.9.0)
|
version: 4.1.1(google-auth-library@8.9.0)
|
||||||
|
isolated-vm:
|
||||||
|
specifier: 4.7.2
|
||||||
|
version: 4.7.2
|
||||||
ky:
|
ky:
|
||||||
specifier: 1.2.3
|
specifier: 1.2.3
|
||||||
version: 1.2.3
|
version: 1.2.3
|
||||||
@ -1948,6 +1957,9 @@ importers:
|
|||||||
'@typebot.io/tsconfig':
|
'@typebot.io/tsconfig':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../tsconfig
|
version: link:../tsconfig
|
||||||
|
isolated-vm:
|
||||||
|
specifier: 4.7.2
|
||||||
|
version: 4.7.2
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
@ -11994,6 +12006,10 @@ packages:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
|
|
||||||
|
/chownr@1.1.4:
|
||||||
|
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/chownr@2.0.0:
|
/chownr@2.0.0:
|
||||||
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
|
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -12778,6 +12794,11 @@ packages:
|
|||||||
optional: true
|
optional: true
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/deep-extend@0.6.0:
|
||||||
|
resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
|
||||||
|
engines: {node: '>=4.0.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/deep-is@0.1.4:
|
/deep-is@0.1.4:
|
||||||
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
|
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
|
||||||
|
|
||||||
@ -12875,7 +12896,6 @@ packages:
|
|||||||
/detect-libc@2.0.2:
|
/detect-libc@2.0.2:
|
||||||
resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==}
|
resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/detect-newline@3.1.0:
|
/detect-newline@3.1.0:
|
||||||
resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
|
resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
|
||||||
@ -13125,6 +13145,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
|
resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
|
||||||
|
/end-of-stream@1.4.4:
|
||||||
|
resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
|
||||||
|
dependencies:
|
||||||
|
once: 1.4.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/engine.io-client@6.5.3:
|
/engine.io-client@6.5.3:
|
||||||
resolution: {integrity: sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==}
|
resolution: {integrity: sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -14196,6 +14222,11 @@ packages:
|
|||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/expand-template@2.0.3:
|
||||||
|
resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/expect@29.7.0:
|
/expect@29.7.0:
|
||||||
resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==}
|
resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==}
|
||||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||||
@ -14541,6 +14572,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
|
resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
|
|
||||||
|
/fs-constants@1.0.0:
|
||||||
|
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/fs-extra@11.2.0:
|
/fs-extra@11.2.0:
|
||||||
resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==}
|
resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==}
|
||||||
engines: {node: '>=14.14'}
|
engines: {node: '>=14.14'}
|
||||||
@ -14676,6 +14711,10 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
resolve-pkg-maps: 1.0.0
|
resolve-pkg-maps: 1.0.0
|
||||||
|
|
||||||
|
/github-from-package@0.0.0:
|
||||||
|
resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/glob-parent@5.1.2:
|
/glob-parent@5.1.2:
|
||||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
@ -15773,6 +15812,14 @@ packages:
|
|||||||
/isexe@2.0.0:
|
/isexe@2.0.0:
|
||||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||||
|
|
||||||
|
/isolated-vm@4.7.2:
|
||||||
|
resolution: {integrity: sha512-JVEs5gzWObzZK5+OlBplCdYSpokMcdhLSs/xWYYxmYWVfOOFF4oZJsYh7E/FmfX8e7gMioXMpMMeEyX1afuKrg==}
|
||||||
|
engines: {node: '>=16.0.0'}
|
||||||
|
requiresBuild: true
|
||||||
|
dependencies:
|
||||||
|
prebuild-install: 7.1.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/isomorphic-fetch@3.0.0:
|
/isomorphic-fetch@3.0.0:
|
||||||
resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==}
|
resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -18227,6 +18274,10 @@ packages:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- encoding
|
- encoding
|
||||||
|
|
||||||
|
/mkdirp-classic@0.5.3:
|
||||||
|
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/mkdirp@0.5.6:
|
/mkdirp@0.5.6:
|
||||||
resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
|
resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@ -18292,6 +18343,10 @@ packages:
|
|||||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
/napi-build-utils@1.0.2:
|
||||||
|
resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/natural-compare-lite@1.4.0:
|
/natural-compare-lite@1.4.0:
|
||||||
resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==}
|
resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -18453,6 +18508,13 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
lower-case: 1.1.4
|
lower-case: 1.1.4
|
||||||
|
|
||||||
|
/node-abi@3.62.0:
|
||||||
|
resolution: {integrity: sha512-CPMcGa+y33xuL1E0TcNIu4YyaZCxnnvkVaEXrsosR3FxN+fV8xvb7Mzpb7IgKler10qeMkE6+Dp8qJhpzdq35g==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
dependencies:
|
||||||
|
semver: 7.6.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/node-domexception@1.0.0:
|
/node-domexception@1.0.0:
|
||||||
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
|
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
|
||||||
engines: {node: '>=10.5.0'}
|
engines: {node: '>=10.5.0'}
|
||||||
@ -19587,6 +19649,25 @@ packages:
|
|||||||
resolution: {integrity: sha512-gympg+T2Z1fG1unB8NH29yHJwnEaCH37Z32diPDku316OTnRPeMbiRV9kTrfZpocXjdfnWuFUl/Mj4BHaf6gnw==}
|
resolution: {integrity: sha512-gympg+T2Z1fG1unB8NH29yHJwnEaCH37Z32diPDku316OTnRPeMbiRV9kTrfZpocXjdfnWuFUl/Mj4BHaf6gnw==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/prebuild-install@7.1.2:
|
||||||
|
resolution: {integrity: sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
detect-libc: 2.0.2
|
||||||
|
expand-template: 2.0.3
|
||||||
|
github-from-package: 0.0.0
|
||||||
|
minimist: 1.2.8
|
||||||
|
mkdirp-classic: 0.5.3
|
||||||
|
napi-build-utils: 1.0.2
|
||||||
|
node-abi: 3.62.0
|
||||||
|
pump: 3.0.0
|
||||||
|
rc: 1.2.8
|
||||||
|
simple-get: 4.0.1
|
||||||
|
tar-fs: 2.1.1
|
||||||
|
tunnel-agent: 0.6.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/prelude-ls@1.2.1:
|
/prelude-ls@1.2.1:
|
||||||
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
@ -19721,6 +19802,13 @@ packages:
|
|||||||
is-ip: 3.1.0
|
is-ip: 3.1.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/pump@3.0.0:
|
||||||
|
resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==}
|
||||||
|
dependencies:
|
||||||
|
end-of-stream: 1.4.4
|
||||||
|
once: 1.4.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/punycode@2.3.1:
|
/punycode@2.3.1:
|
||||||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@ -19819,6 +19907,16 @@ packages:
|
|||||||
iconv-lite: 0.4.24
|
iconv-lite: 0.4.24
|
||||||
unpipe: 1.0.0
|
unpipe: 1.0.0
|
||||||
|
|
||||||
|
/rc@1.2.8:
|
||||||
|
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
deep-extend: 0.6.0
|
||||||
|
ini: 1.3.8
|
||||||
|
minimist: 1.2.8
|
||||||
|
strip-json-comments: 2.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/react-clientside-effect@1.2.6(react@18.2.0):
|
/react-clientside-effect@1.2.6(react@18.2.0):
|
||||||
resolution: {integrity: sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==}
|
resolution: {integrity: sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -20874,6 +20972,18 @@ packages:
|
|||||||
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
|
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
|
||||||
|
/simple-concat@1.0.1:
|
||||||
|
resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/simple-get@4.0.1:
|
||||||
|
resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==}
|
||||||
|
dependencies:
|
||||||
|
decompress-response: 6.0.0
|
||||||
|
once: 1.4.0
|
||||||
|
simple-concat: 1.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/simple-swizzle@0.2.2:
|
/simple-swizzle@0.2.2:
|
||||||
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
|
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -21353,6 +21463,11 @@ packages:
|
|||||||
min-indent: 1.0.1
|
min-indent: 1.0.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/strip-json-comments@2.0.1:
|
||||||
|
resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/strip-json-comments@3.1.1:
|
/strip-json-comments@3.1.1:
|
||||||
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -21684,6 +21799,26 @@ packages:
|
|||||||
resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
|
resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
/tar-fs@2.1.1:
|
||||||
|
resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==}
|
||||||
|
dependencies:
|
||||||
|
chownr: 1.1.4
|
||||||
|
mkdirp-classic: 0.5.3
|
||||||
|
pump: 3.0.0
|
||||||
|
tar-stream: 2.2.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/tar-stream@2.2.0:
|
||||||
|
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
dependencies:
|
||||||
|
bl: 4.1.0
|
||||||
|
end-of-stream: 1.4.4
|
||||||
|
fs-constants: 1.0.0
|
||||||
|
inherits: 2.0.4
|
||||||
|
readable-stream: 3.6.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/tar@6.2.0:
|
/tar@6.2.0:
|
||||||
resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==}
|
resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -22065,6 +22200,12 @@ packages:
|
|||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/tunnel-agent@0.6.0:
|
||||||
|
resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
|
||||||
|
dependencies:
|
||||||
|
safe-buffer: 5.2.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/turbo-darwin-64@1.11.3:
|
/turbo-darwin-64@1.11.3:
|
||||||
resolution: {integrity: sha512-IsOOg2bVbIt3o/X8Ew9fbQp5t1hTHN3fGNQYrPQwMR2W1kIAC6RfbVD4A9OeibPGyEPUpwOH79hZ9ydFH5kifw==}
|
resolution: {integrity: sha512-IsOOg2bVbIt3o/X8Ew9fbQp5t1hTHN3fGNQYrPQwMR2W1kIAC6RfbVD4A9OeibPGyEPUpwOH79hZ9ydFH5kifw==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
|
Reference in New Issue
Block a user