Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
84ecf105c2 | ||
![]() |
c07a02ef31 | ||
![]() |
3c44f55f19 |
@@ -20,6 +20,7 @@
|
|||||||
"db:migrate": "node ./bin/database/convert-migrations.js && knex migrate:latest"
|
"db:migrate": "node ./bin/database/convert-migrations.js && knex migrate:latest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@atproto/api": "^0.12.13",
|
||||||
"@bull-board/express": "^3.10.1",
|
"@bull-board/express": "^3.10.1",
|
||||||
"@casl/ability": "^6.5.0",
|
"@casl/ability": "^6.5.0",
|
||||||
"@graphql-tools/graphql-file-loader": "^7.3.4",
|
"@graphql-tools/graphql-file-loader": "^7.3.4",
|
||||||
|
@@ -0,0 +1,41 @@
|
|||||||
|
import { BskyAgent, RichText } from '@atproto/api';
|
||||||
|
|
||||||
|
import defineAction from '../../../../helpers/define-action.js';
|
||||||
|
|
||||||
|
export default defineAction({
|
||||||
|
name: 'Create post',
|
||||||
|
key: 'createPost',
|
||||||
|
description: 'Creates a new post.',
|
||||||
|
arguments: [
|
||||||
|
{
|
||||||
|
label: 'Text',
|
||||||
|
key: 'text',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
variables: true,
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
async run($) {
|
||||||
|
const text = $.step.parameters.text;
|
||||||
|
const agent = new BskyAgent({ service: 'https://bsky.social/xrpc' });
|
||||||
|
const richText = new RichText({ text });
|
||||||
|
await richText.detectFacets(agent);
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
repo: $.auth.data.did,
|
||||||
|
collection: 'app.bsky.feed.post',
|
||||||
|
record: {
|
||||||
|
$type: 'app.bsky.feed.post',
|
||||||
|
text: richText.text,
|
||||||
|
facets: richText.facets,
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const { data } = await $.http.post('/com.atproto.repo.createRecord', body);
|
||||||
|
|
||||||
|
$.setActionItem({ raw: data });
|
||||||
|
},
|
||||||
|
});
|
4
packages/backend/src/apps/bluesky/actions/index.js
Normal file
4
packages/backend/src/apps/bluesky/actions/index.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import createPost from './create-post/index.js';
|
||||||
|
import searchPostByUrl from './search-post-by-url/index.js';
|
||||||
|
|
||||||
|
export default [createPost, searchPostByUrl];
|
@@ -0,0 +1,35 @@
|
|||||||
|
import defineAction from '../../../../helpers/define-action.js';
|
||||||
|
|
||||||
|
export default defineAction({
|
||||||
|
name: 'Search post by url',
|
||||||
|
key: 'searchPostByUrl',
|
||||||
|
description: 'Searches a post in a thread by url.',
|
||||||
|
arguments: [
|
||||||
|
{
|
||||||
|
label: 'Post Url',
|
||||||
|
key: 'postUrl',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
variables: true,
|
||||||
|
description: 'Enter whole post url here.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
async run($) {
|
||||||
|
const postUrl = $.step.parameters.postUrl;
|
||||||
|
const urlParts = postUrl.split('/');
|
||||||
|
const handle = urlParts[urlParts.length - 3];
|
||||||
|
const postId = urlParts[urlParts.length - 1];
|
||||||
|
const uri = `at://${handle}/app.bsky.feed.post/${postId}`;
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
uri,
|
||||||
|
};
|
||||||
|
|
||||||
|
const { data } = await $.http.get('/app.bsky.feed.getPostThread', {
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
|
||||||
|
$.setActionItem({ raw: data });
|
||||||
|
},
|
||||||
|
});
|
4
packages/backend/src/apps/bluesky/assets/favicon.svg
Normal file
4
packages/backend/src/apps/bluesky/assets/favicon.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-50 -50 430 390" fill="#1185fd" aria-hidden="true">
|
||||||
|
<path d="M180 141.964C163.699 110.262 119.308 51.1817 78.0347 22.044C38.4971 -5.86834 23.414 -1.03207 13.526 3.43594C2.08093 8.60755 0 26.1785 0 36.5164C0 46.8542 5.66748 121.272 9.36416 133.694C21.5786 174.738 65.0603 188.607 105.104 184.156C107.151 183.852 109.227 183.572 111.329 183.312C109.267 183.642 107.19 183.924 105.104 184.156C46.4204 192.847 -5.69621 214.233 62.6582 290.33C137.848 368.18 165.705 273.637 180 225.702C194.295 273.637 210.76 364.771 295.995 290.33C360 225.702 313.58 192.85 254.896 184.158C252.81 183.926 250.733 183.645 248.671 183.315C250.773 183.574 252.849 183.855 254.896 184.158C294.94 188.61 338.421 174.74 350.636 133.697C354.333 121.275 360 46.8568 360 36.519C360 26.1811 357.919 8.61012 346.474 3.43851C336.586 -1.02949 321.503 -5.86576 281.965 22.0466C240.692 51.1843 196.301 110.262 180 141.964Z">
|
||||||
|
</path>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 956 B |
34
packages/backend/src/apps/bluesky/auth/index.js
Normal file
34
packages/backend/src/apps/bluesky/auth/index.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import verifyCredentials from './verify-credentials.js';
|
||||||
|
import isStillVerified from './is-still-verified.js';
|
||||||
|
import refreshToken from './refresh-token.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
key: 'handle',
|
||||||
|
label: 'Your Bluesky Handle',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
readOnly: false,
|
||||||
|
value: null,
|
||||||
|
placeholder: null,
|
||||||
|
description: '',
|
||||||
|
clickToCopy: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'password',
|
||||||
|
label: 'Your Bluesky Password',
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
readOnly: false,
|
||||||
|
value: null,
|
||||||
|
placeholder: null,
|
||||||
|
description: '',
|
||||||
|
clickToCopy: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
verifyCredentials,
|
||||||
|
isStillVerified,
|
||||||
|
refreshToken,
|
||||||
|
};
|
@@ -2,7 +2,7 @@ import getCurrentUser from '../common/get-current-user.js';
|
|||||||
|
|
||||||
const isStillVerified = async ($) => {
|
const isStillVerified = async ($) => {
|
||||||
const currentUser = await getCurrentUser($);
|
const currentUser = await getCurrentUser($);
|
||||||
return !!currentUser.id;
|
return !!currentUser.did;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default isStillVerified;
|
export default isStillVerified;
|
24
packages/backend/src/apps/bluesky/auth/refresh-token.js
Normal file
24
packages/backend/src/apps/bluesky/auth/refresh-token.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
const refreshToken = async ($) => {
|
||||||
|
const { refreshJwt } = $.auth.data;
|
||||||
|
|
||||||
|
const { data } = await $.http.post(
|
||||||
|
'/com.atproto.server.refreshSession',
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${refreshJwt}`,
|
||||||
|
},
|
||||||
|
additionalProperties: {
|
||||||
|
skipAddingAuthHeader: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await $.auth.set({
|
||||||
|
accessJwt: data.accessJwt,
|
||||||
|
refreshJwt: data.refreshJwt,
|
||||||
|
did: data.did,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export default refreshToken;
|
20
packages/backend/src/apps/bluesky/auth/verify-credentials.js
Normal file
20
packages/backend/src/apps/bluesky/auth/verify-credentials.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
const verifyCredentials = async ($) => {
|
||||||
|
const handle = $.auth.data.handle;
|
||||||
|
const password = $.auth.data.password;
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
identifier: handle,
|
||||||
|
password,
|
||||||
|
};
|
||||||
|
|
||||||
|
const { data } = await $.http.post('/com.atproto.server.createSession', body);
|
||||||
|
|
||||||
|
await $.auth.set({
|
||||||
|
accessJwt: data.accessJwt,
|
||||||
|
refreshJwt: data.refreshJwt,
|
||||||
|
did: data.did,
|
||||||
|
screenName: data.handle,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export default verifyCredentials;
|
12
packages/backend/src/apps/bluesky/common/add-auth-header.js
Normal file
12
packages/backend/src/apps/bluesky/common/add-auth-header.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
const addAuthHeader = ($, requestConfig) => {
|
||||||
|
if (requestConfig.additionalProperties?.skipAddingAuthHeader)
|
||||||
|
return requestConfig;
|
||||||
|
|
||||||
|
if ($.auth.data?.accessJwt) {
|
||||||
|
requestConfig.headers.Authorization = `Bearer ${$.auth.data.accessJwt}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return requestConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default addAuthHeader;
|
15
packages/backend/src/apps/bluesky/common/get-current-user.js
Normal file
15
packages/backend/src/apps/bluesky/common/get-current-user.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
const getCurrentUser = async ($) => {
|
||||||
|
const handle = $.auth.data.handle;
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
actor: handle,
|
||||||
|
};
|
||||||
|
|
||||||
|
const { data: currentUser } = await $.http.get('/app.bsky.actor.getProfile', {
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
|
||||||
|
return currentUser;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getCurrentUser;
|
18
packages/backend/src/apps/bluesky/index.js
Normal file
18
packages/backend/src/apps/bluesky/index.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import defineApp from '../../helpers/define-app.js';
|
||||||
|
import addAuthHeader from './common/add-auth-header.js';
|
||||||
|
import auth from './auth/index.js';
|
||||||
|
import actions from './actions/index.js';
|
||||||
|
|
||||||
|
export default defineApp({
|
||||||
|
name: 'Bluesky',
|
||||||
|
key: 'bluesky',
|
||||||
|
iconUrl: '{BASE_URL}/apps/bluesky/assets/favicon.svg',
|
||||||
|
authDocUrl: '{DOCS_URL}/apps/bluesky/connection',
|
||||||
|
supportsConnections: true,
|
||||||
|
baseUrl: 'https://bluesky.app',
|
||||||
|
apiBaseUrl: 'https://bsky.social/xrpc',
|
||||||
|
primaryColor: '1185fd',
|
||||||
|
beforeRequest: [addAuthHeader],
|
||||||
|
auth,
|
||||||
|
actions,
|
||||||
|
});
|
@@ -1 +0,0 @@
|
|||||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 222.61 155.27"><defs><style>.cls-1{fill:#00bf6f;}</style></defs><title>Goldie_Sabaeus_RGB</title><path id="_Compound_Path_" data-name="<Compound Path>" class="cls-1" d="M249,141.26a26.52,26.52,0,0,0-6.29.78,81.08,81.08,0,0,0-64.19-59.81c-1.4-.25-2.66-.44-4.09-.62h0c.24-7.66.59-16.51,11.86-24.47l-1.78-4.49s-22,6.82-24.49,25.61c-1.09-5.11-11.33-11.51-16.4-12.72l-2.52,4.07s6.72,3.36,8.36,12.63h0A81.08,81.08,0,0,0,85.24,142a26.3,26.3,0,1,0,3.32,50,80.63,80.63,0,0,0,8.54,15.89l21.83-14.71-.19-.24c-5.77-7.42-9.3-18.34-9.9-29.21-.65-12,2.27-23.9,9.93-30.9,15.79-13.44,33-7.31,43.74,5.57h2.89c10.77-12.88,28-19,43.74-5.57,7.65,7,10.58,18.91,9.93,30.9-.59,10.87-4.12,21.79-9.9,29.21l-.19.24,21.83,14.71A80.63,80.63,0,0,0,239.37,192,26.29,26.29,0,1,0,249,141.26Zm-170.53,34a7.76,7.76,0,0,1,0-15.52,7.83,7.83,0,0,1,4.35,1.34,117.87,117.87,0,0,0,.83,12.19A7.76,7.76,0,0,1,78.44,175.31Zm171,0a7.76,7.76,0,0,1-5.18-2,117.87,117.87,0,0,0,.83-12.19,7.75,7.75,0,0,1,12.1,6.43A7.74,7.74,0,0,1,249.48,175.31Z" transform="translate(-52.66 -52.66)"/></svg>
|
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,24 +0,0 @@
|
|||||||
import crypto from 'crypto';
|
|
||||||
import { URLSearchParams } from 'url';
|
|
||||||
|
|
||||||
export default async function generateAuthUrl($) {
|
|
||||||
const oauthRedirectUrlField = $.app.auth.fields.find(
|
|
||||||
(field) => field.key == 'oAuthRedirectUrl'
|
|
||||||
);
|
|
||||||
const redirectUri = oauthRedirectUrlField.value;
|
|
||||||
const state = crypto.randomBytes(100).toString('base64url');
|
|
||||||
|
|
||||||
const searchParams = new URLSearchParams({
|
|
||||||
client_id: $.auth.data.clientId,
|
|
||||||
redirect_uri: redirectUri,
|
|
||||||
response_type: 'code',
|
|
||||||
state,
|
|
||||||
});
|
|
||||||
|
|
||||||
const url = `https://api.surveymonkey.com/oauth/authorize?${searchParams.toString()}`;
|
|
||||||
|
|
||||||
await $.auth.set({
|
|
||||||
url,
|
|
||||||
originalState: state,
|
|
||||||
});
|
|
||||||
}
|
|
@@ -1,46 +0,0 @@
|
|||||||
import generateAuthUrl from './generate-auth-url.js';
|
|
||||||
import verifyCredentials from './verify-credentials.js';
|
|
||||||
import isStillVerified from './is-still-verified.js';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
key: 'oAuthRedirectUrl',
|
|
||||||
label: 'OAuth Redirect URL',
|
|
||||||
type: 'string',
|
|
||||||
required: true,
|
|
||||||
readOnly: true,
|
|
||||||
value: '{WEB_APP_URL}/app/surveymonkey/connections/add',
|
|
||||||
placeholder: null,
|
|
||||||
description:
|
|
||||||
'When asked to input a redirect URL in SurveyMonkey, enter the URL above.',
|
|
||||||
clickToCopy: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'clientId',
|
|
||||||
label: 'Client ID',
|
|
||||||
type: 'string',
|
|
||||||
required: true,
|
|
||||||
readOnly: false,
|
|
||||||
value: null,
|
|
||||||
placeholder: null,
|
|
||||||
description: null,
|
|
||||||
clickToCopy: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'clientSecret',
|
|
||||||
label: 'Client Secret',
|
|
||||||
type: 'string',
|
|
||||||
required: true,
|
|
||||||
readOnly: false,
|
|
||||||
value: null,
|
|
||||||
placeholder: null,
|
|
||||||
description: null,
|
|
||||||
clickToCopy: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
generateAuthUrl,
|
|
||||||
verifyCredentials,
|
|
||||||
isStillVerified,
|
|
||||||
};
|
|
@@ -1,48 +0,0 @@
|
|||||||
import getCurrentUser from '../common/get-current-user.js';
|
|
||||||
|
|
||||||
const verifyCredentials = async ($) => {
|
|
||||||
if ($.auth.data.originalState !== $.auth.data.state) {
|
|
||||||
throw new Error("The 'state' parameter does not match.");
|
|
||||||
}
|
|
||||||
|
|
||||||
const oauthRedirectUrlField = $.app.auth.fields.find(
|
|
||||||
(field) => field.key == 'oAuthRedirectUrl'
|
|
||||||
);
|
|
||||||
const redirectUri = oauthRedirectUrlField.value;
|
|
||||||
const { data } = await $.http.post(
|
|
||||||
'https://api.surveymonkey.com/oauth/token',
|
|
||||||
{
|
|
||||||
client_secret: $.auth.data.clientSecret,
|
|
||||||
code: $.auth.data.code,
|
|
||||||
redirect_uri: redirectUri,
|
|
||||||
client_id: $.auth.data.clientId,
|
|
||||||
grant_type: 'authorization_code',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
await $.auth.set({
|
|
||||||
accessToken: data.access_token,
|
|
||||||
tokenType: data.token_type,
|
|
||||||
accessUrl: data.access_url,
|
|
||||||
expiresIn: data.expires_in,
|
|
||||||
});
|
|
||||||
|
|
||||||
const currentUser = await getCurrentUser($);
|
|
||||||
|
|
||||||
const screenName = [currentUser.username, currentUser.email]
|
|
||||||
.filter(Boolean)
|
|
||||||
.join(' @ ');
|
|
||||||
|
|
||||||
await $.auth.set({
|
|
||||||
clientId: $.auth.data.clientId,
|
|
||||||
clientSecret: $.auth.data.clientSecret,
|
|
||||||
screenName,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export default verifyCredentials;
|
|
@@ -1,9 +0,0 @@
|
|||||||
const addAuthHeader = ($, requestConfig) => {
|
|
||||||
if ($.auth.data?.accessToken) {
|
|
||||||
requestConfig.headers.Authorization = `${$.auth.data.tokenType} ${$.auth.data.accessToken}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return requestConfig;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default addAuthHeader;
|
|
@@ -1,6 +0,0 @@
|
|||||||
const getCurrentUser = async ($) => {
|
|
||||||
const { data: currentUser } = await $.http.get('/v3/users/me');
|
|
||||||
return currentUser;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default getCurrentUser;
|
|
@@ -1,11 +0,0 @@
|
|||||||
const setBaseUrl = ($, requestConfig) => {
|
|
||||||
const accessUrl = $.auth.data.accessUrl;
|
|
||||||
|
|
||||||
if (accessUrl) {
|
|
||||||
requestConfig.baseURL = accessUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return requestConfig;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default setBaseUrl;
|
|
@@ -1,3 +0,0 @@
|
|||||||
import listSurveys from './list-surveys/index.js';
|
|
||||||
|
|
||||||
export default [listSurveys];
|
|
@@ -1,38 +0,0 @@
|
|||||||
export default {
|
|
||||||
name: 'List surveys',
|
|
||||||
key: 'listSurveys',
|
|
||||||
|
|
||||||
async run($) {
|
|
||||||
const surveys = {
|
|
||||||
data: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
const params = {
|
|
||||||
page: 1,
|
|
||||||
per_page: 100,
|
|
||||||
sort_by: 'date_modified',
|
|
||||||
sort_order: 'DESC',
|
|
||||||
};
|
|
||||||
|
|
||||||
let fetchedSum = 0;
|
|
||||||
let total;
|
|
||||||
do {
|
|
||||||
const { data } = await $.http.get(`/v3/surveys`, { params });
|
|
||||||
|
|
||||||
params.page = params.page + 1;
|
|
||||||
fetchedSum = fetchedSum + params.per_page;
|
|
||||||
total = data.total;
|
|
||||||
|
|
||||||
if (data.data) {
|
|
||||||
for (const survey of data.data) {
|
|
||||||
surveys.data.push({
|
|
||||||
value: survey.id,
|
|
||||||
name: survey.title,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (fetchedSum <= total);
|
|
||||||
|
|
||||||
return surveys;
|
|
||||||
},
|
|
||||||
};
|
|
@@ -1,21 +0,0 @@
|
|||||||
import defineApp from '../../helpers/define-app.js';
|
|
||||||
import addAuthHeader from './common/add-auth-header.js';
|
|
||||||
import auth from './auth/index.js';
|
|
||||||
import setBaseUrl from './common/set-base-url.js';
|
|
||||||
import triggers from './triggers/index.js';
|
|
||||||
import dynamicData from './dynamic-data/index.js';
|
|
||||||
|
|
||||||
export default defineApp({
|
|
||||||
name: 'SurveyMonkey',
|
|
||||||
key: 'surveymonkey',
|
|
||||||
baseUrl: 'https://www.surveymonkey.com',
|
|
||||||
apiBaseUrl: '',
|
|
||||||
iconUrl: '{BASE_URL}/apps/surveymonkey/assets/favicon.svg',
|
|
||||||
authDocUrl: '{DOCS_URL}/apps/surveymonkey/connection',
|
|
||||||
primaryColor: '00bf6f',
|
|
||||||
supportsConnections: true,
|
|
||||||
beforeRequest: [setBaseUrl, addAuthHeader],
|
|
||||||
auth,
|
|
||||||
triggers,
|
|
||||||
dynamicData,
|
|
||||||
});
|
|
@@ -1,3 +0,0 @@
|
|||||||
import newResponseNotification from './new-response-notification/index.js';
|
|
||||||
|
|
||||||
export default [newResponseNotification];
|
|
@@ -1,78 +0,0 @@
|
|||||||
import Crypto from 'crypto';
|
|
||||||
import isEmpty from 'lodash/isEmpty.js';
|
|
||||||
import defineTrigger from '../../../../helpers/define-trigger.js';
|
|
||||||
|
|
||||||
export default defineTrigger({
|
|
||||||
name: 'New response notification',
|
|
||||||
key: 'newResponseNotification',
|
|
||||||
type: 'webhook',
|
|
||||||
description: 'Triggers a notification upon the completion of your survey.',
|
|
||||||
arguments: [
|
|
||||||
{
|
|
||||||
label: 'Survey',
|
|
||||||
key: 'surveyId',
|
|
||||||
type: 'dropdown',
|
|
||||||
required: true,
|
|
||||||
description: '',
|
|
||||||
variables: true,
|
|
||||||
source: {
|
|
||||||
type: 'query',
|
|
||||||
name: 'getDynamicData',
|
|
||||||
arguments: [
|
|
||||||
{
|
|
||||||
name: 'key',
|
|
||||||
value: 'listSurveys',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
async run($) {
|
|
||||||
const dataItem = {
|
|
||||||
raw: $.request.body,
|
|
||||||
meta: {
|
|
||||||
internalId: Crypto.randomUUID(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
$.pushTriggerItem(dataItem);
|
|
||||||
},
|
|
||||||
|
|
||||||
async testRun($) {
|
|
||||||
const lastExecutionStep = await $.getLastExecutionStep();
|
|
||||||
|
|
||||||
if (!isEmpty(lastExecutionStep?.dataOut)) {
|
|
||||||
$.pushTriggerItem({
|
|
||||||
raw: lastExecutionStep.dataOut,
|
|
||||||
meta: {
|
|
||||||
internalId: '',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
async registerHook($) {
|
|
||||||
const surveyId = $.step.parameters.surveyId;
|
|
||||||
|
|
||||||
const body = JSON.stringify({
|
|
||||||
name: $.flow.id,
|
|
||||||
subscription_url: $.webhookUrl,
|
|
||||||
event_type: 'response_completed',
|
|
||||||
object_type: 'survey',
|
|
||||||
object_ids: [surveyId],
|
|
||||||
});
|
|
||||||
|
|
||||||
const { data } = await $.http.post('/v3/webhooks?bypass_ping=true', body, {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await $.flow.setRemoteWebhookId(data.id);
|
|
||||||
},
|
|
||||||
|
|
||||||
async unregisterHook($) {
|
|
||||||
await $.http.delete(`/v3/webhooks/${$.flow.remoteWebhookId}`);
|
|
||||||
},
|
|
||||||
});
|
|
@@ -52,7 +52,7 @@ const appConfig = {
|
|||||||
isDev: appEnv === 'development',
|
isDev: appEnv === 'development',
|
||||||
isTest: appEnv === 'test',
|
isTest: appEnv === 'test',
|
||||||
isProd: appEnv === 'production',
|
isProd: appEnv === 'production',
|
||||||
version: '0.12.0',
|
version: '0.11.0',
|
||||||
postgresDatabase: process.env.POSTGRES_DATABASE || 'automatisch_development',
|
postgresDatabase: process.env.POSTGRES_DATABASE || 'automatisch_development',
|
||||||
postgresSchema: process.env.POSTGRES_SCHEMA || 'public',
|
postgresSchema: process.env.POSTGRES_SCHEMA || 'public',
|
||||||
postgresPort: parseInt(process.env.POSTGRES_PORT || '5432'),
|
postgresPort: parseInt(process.env.POSTGRES_PORT || '5432'),
|
||||||
|
@@ -10,7 +10,7 @@ describe('GET /api/v1/automatisch/version', () => {
|
|||||||
|
|
||||||
const expectedPayload = {
|
const expectedPayload = {
|
||||||
data: {
|
data: {
|
||||||
version: '0.12.0',
|
version: '0.11.0',
|
||||||
},
|
},
|
||||||
meta: {
|
meta: {
|
||||||
count: 1,
|
count: 1,
|
||||||
|
@@ -1,11 +0,0 @@
|
|||||||
export async function up(knex) {
|
|
||||||
return knex.schema.alterTable('datastore', (table) => {
|
|
||||||
table.text('value').alter();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function down(knex) {
|
|
||||||
return knex.schema.alterTable('datastore', (table) => {
|
|
||||||
table.string('value').alter();
|
|
||||||
});
|
|
||||||
}
|
|
@@ -50,6 +50,15 @@ export default defineConfig({
|
|||||||
{ text: 'Connection', link: '/apps/appwrite/connection' },
|
{ text: 'Connection', link: '/apps/appwrite/connection' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: 'Bluesky',
|
||||||
|
collapsible: true,
|
||||||
|
collapsed: true,
|
||||||
|
items: [
|
||||||
|
{ text: 'Actions', link: '/apps/bluesky/actions' },
|
||||||
|
{ text: 'Connection', link: '/apps/bluesky/connection' },
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
text: 'Carbone',
|
text: 'Carbone',
|
||||||
collapsible: true,
|
collapsible: true,
|
||||||
@@ -437,14 +446,6 @@ export default defineConfig({
|
|||||||
{ text: 'Connection', link: '/apps/stripe/connection' },
|
{ text: 'Connection', link: '/apps/stripe/connection' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
text: 'SurveyMonkey',
|
|
||||||
collapsible: true,
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
{ text: 'Connection', link: '/apps/surveymonkey/connection' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
text: 'Telegram',
|
text: 'Telegram',
|
||||||
collapsible: true,
|
collapsible: true,
|
||||||
|
14
packages/docs/pages/apps/bluesky/actions.md
Normal file
14
packages/docs/pages/apps/bluesky/actions.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
favicon: /favicons/bluesky.svg
|
||||||
|
items:
|
||||||
|
- name: Create post
|
||||||
|
desc: Creates a new post.
|
||||||
|
- name: Search post by url
|
||||||
|
desc: Searches a post in a thread by url.
|
||||||
|
---
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import CustomListing from '../../components/CustomListing.vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<CustomListing />
|
10
packages/docs/pages/apps/bluesky/connection.md
Normal file
10
packages/docs/pages/apps/bluesky/connection.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Bluesky
|
||||||
|
|
||||||
|
:::info
|
||||||
|
This page explains the steps you need to follow to set up the Bluesky connection in Automatisch. If any of the steps are outdated, please let us know!
|
||||||
|
:::
|
||||||
|
|
||||||
|
1. Enter your `Bluesky Handle` from the page to the `Your Bluesky Handle` field on Automatisch.
|
||||||
|
1. Enter your `Bluesky Password` from the page to the `Your Bluesky Password` field on Automatisch.
|
||||||
|
1. Click **Submit** button on Automatisch.
|
||||||
|
1. Congrats! Start using your new Bluesky connection within the flows.
|
@@ -1,18 +0,0 @@
|
|||||||
# SurveyMonkey
|
|
||||||
|
|
||||||
:::info
|
|
||||||
This page explains the steps you need to follow to set up the SurveyMonkey
|
|
||||||
connection in Automatisch. If any of the steps are outdated, please let us know!
|
|
||||||
:::
|
|
||||||
|
|
||||||
1. Go to the [My Apps page of your SurveyMonkey account](https://developer.surveymonkey.com/apps/) to create a project.
|
|
||||||
2. Click on the **Add a New App** button.
|
|
||||||
3. Fill the form and submit it.
|
|
||||||
4. Go to **Settings** page.
|
|
||||||
5. Copy **OAuth Redirect URL** from Automatisch to **OAuth Redirect URIs** field, and click on the **Submit Changes** button.
|
|
||||||
6. In the same page, go to the **Scopes** section.
|
|
||||||
7. Select **Create/Modify Surveys**, **View Surveys**, **View Collectors**, **View Responses**, **Create/Modify Contacts**, **View Contacts**, **Create/Modify Webhooks**, **View Users** and **View Webhooks** scopes and click on the **Update Scopes** button.
|
|
||||||
8. Copy the **Client ID** value in the same page to the `Client ID` field on Automatisch.
|
|
||||||
9. Copy the **Secret** value in the same page to the `Client Secret` field on Automatisch.
|
|
||||||
10. Click **Submit** button on Automatisch.
|
|
||||||
11. Congrats! Start using your new SurveyMonkey connection within the flows.
|
|
@@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
favicon: /favicons/surveymonkey.svg
|
|
||||||
items:
|
|
||||||
- name: New response notification
|
|
||||||
desc: Triggers a notification upon the completion of your survey.
|
|
||||||
---
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import CustomListing from '../../components/CustomListing.vue'
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<CustomListing />
|
|
@@ -4,6 +4,7 @@ The following integrations are currently supported by Automatisch.
|
|||||||
|
|
||||||
- [Airtable](/apps/airtable/actions)
|
- [Airtable](/apps/airtable/actions)
|
||||||
- [Appwrite](/apps/appwrite/triggers)
|
- [Appwrite](/apps/appwrite/triggers)
|
||||||
|
- [Bluesky](/apps/bluesky/actions)
|
||||||
- [Carbone](/apps/carbone/actions)
|
- [Carbone](/apps/carbone/actions)
|
||||||
- [Datastore](/apps/datastore/actions)
|
- [Datastore](/apps/datastore/actions)
|
||||||
- [DeepL](/apps/deepl/actions)
|
- [DeepL](/apps/deepl/actions)
|
||||||
@@ -46,7 +47,6 @@ The following integrations are currently supported by Automatisch.
|
|||||||
- [Spotify](/apps/spotify/actions)
|
- [Spotify](/apps/spotify/actions)
|
||||||
- [Strava](/apps/strava/actions)
|
- [Strava](/apps/strava/actions)
|
||||||
- [Stripe](/apps/stripe/triggers)
|
- [Stripe](/apps/stripe/triggers)
|
||||||
- [SurveyMonkey](/apps/surveymonkey/triggers)
|
|
||||||
- [Telegram](/apps/telegram-bot/actions)
|
- [Telegram](/apps/telegram-bot/actions)
|
||||||
- [Todoist](/apps/todoist/triggers)
|
- [Todoist](/apps/todoist/triggers)
|
||||||
- [Trello](/apps/trello/actions)
|
- [Trello](/apps/trello/actions)
|
||||||
|
4
packages/docs/pages/public/favicons/bluesky.svg
Normal file
4
packages/docs/pages/public/favicons/bluesky.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-50 -50 430 390" fill="#1185fd" aria-hidden="true">
|
||||||
|
<path d="M180 141.964C163.699 110.262 119.308 51.1817 78.0347 22.044C38.4971 -5.86834 23.414 -1.03207 13.526 3.43594C2.08093 8.60755 0 26.1785 0 36.5164C0 46.8542 5.66748 121.272 9.36416 133.694C21.5786 174.738 65.0603 188.607 105.104 184.156C107.151 183.852 109.227 183.572 111.329 183.312C109.267 183.642 107.19 183.924 105.104 184.156C46.4204 192.847 -5.69621 214.233 62.6582 290.33C137.848 368.18 165.705 273.637 180 225.702C194.295 273.637 210.76 364.771 295.995 290.33C360 225.702 313.58 192.85 254.896 184.158C252.81 183.926 250.733 183.645 248.671 183.315C250.773 183.574 252.849 183.855 254.896 184.158C294.94 188.61 338.421 174.74 350.636 133.697C354.333 121.275 360 46.8568 360 36.519C360 26.1811 357.919 8.61012 346.474 3.43851C336.586 -1.02949 321.503 -5.86576 281.965 22.0466C240.692 51.1843 196.301 110.262 180 141.964Z">
|
||||||
|
</path>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 956 B |
@@ -1 +0,0 @@
|
|||||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 222.61 155.27"><defs><style>.cls-1{fill:#00bf6f;}</style></defs><title>Goldie_Sabaeus_RGB</title><path id="_Compound_Path_" data-name="<Compound Path>" class="cls-1" d="M249,141.26a26.52,26.52,0,0,0-6.29.78,81.08,81.08,0,0,0-64.19-59.81c-1.4-.25-2.66-.44-4.09-.62h0c.24-7.66.59-16.51,11.86-24.47l-1.78-4.49s-22,6.82-24.49,25.61c-1.09-5.11-11.33-11.51-16.4-12.72l-2.52,4.07s6.72,3.36,8.36,12.63h0A81.08,81.08,0,0,0,85.24,142a26.3,26.3,0,1,0,3.32,50,80.63,80.63,0,0,0,8.54,15.89l21.83-14.71-.19-.24c-5.77-7.42-9.3-18.34-9.9-29.21-.65-12,2.27-23.9,9.93-30.9,15.79-13.44,33-7.31,43.74,5.57h2.89c10.77-12.88,28-19,43.74-5.57,7.65,7,10.58,18.91,9.93,30.9-.59,10.87-4.12,21.79-9.9,29.21l-.19.24,21.83,14.71A80.63,80.63,0,0,0,239.37,192,26.29,26.29,0,1,0,249,141.26Zm-170.53,34a7.76,7.76,0,0,1,0-15.52,7.83,7.83,0,0,1,4.35,1.34,117.87,117.87,0,0,0,.83,12.19A7.76,7.76,0,0,1,78.44,175.31Zm171,0a7.76,7.76,0,0,1-5.18-2,117.87,117.87,0,0,0,.83-12.19,7.75,7.75,0,0,1,12.1,6.43A7.74,7.74,0,0,1,249.48,175.31Z" transform="translate(-52.66 -52.66)"/></svg>
|
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -7,7 +7,6 @@
|
|||||||
"@apollo/client": "^3.6.9",
|
"@apollo/client": "^3.6.9",
|
||||||
"@casl/ability": "^6.5.0",
|
"@casl/ability": "^6.5.0",
|
||||||
"@casl/react": "^3.1.0",
|
"@casl/react": "^3.1.0",
|
||||||
"@dagrejs/dagre": "^1.1.2",
|
|
||||||
"@emotion/react": "^11.4.1",
|
"@emotion/react": "^11.4.1",
|
||||||
"@emotion/styled": "^11.3.0",
|
"@emotion/styled": "^11.3.0",
|
||||||
"@hookform/resolvers": "^2.8.8",
|
"@hookform/resolvers": "^2.8.8",
|
||||||
@@ -33,7 +32,6 @@
|
|||||||
"react-router-dom": "^6.0.2",
|
"react-router-dom": "^6.0.2",
|
||||||
"react-scripts": "5.0.0",
|
"react-scripts": "5.0.0",
|
||||||
"react-window": "^1.8.9",
|
"react-window": "^1.8.9",
|
||||||
"reactflow": "^11.11.2",
|
|
||||||
"slate": "^0.94.1",
|
"slate": "^0.94.1",
|
||||||
"slate-history": "^0.93.0",
|
"slate-history": "^0.93.0",
|
||||||
"slate-react": "^0.94.2",
|
"slate-react": "^0.94.2",
|
||||||
|
@@ -36,7 +36,7 @@ function AdminApplicationSettings(props) {
|
|||||||
|
|
||||||
const handleSubmit = async (values) => {
|
const handleSubmit = async (values) => {
|
||||||
try {
|
try {
|
||||||
if (!appConfig?.data) {
|
if (!appConfig.data) {
|
||||||
await createAppConfig({
|
await createAppConfig({
|
||||||
variables: {
|
variables: {
|
||||||
input: { key: props.appKey, ...values },
|
input: { key: props.appKey, ...values },
|
||||||
@@ -69,7 +69,6 @@ function AdminApplicationSettings(props) {
|
|||||||
}),
|
}),
|
||||||
[appConfig?.data],
|
[appConfig?.data],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form
|
<Form
|
||||||
defaultValues={defaultValues}
|
defaultValues={defaultValues}
|
||||||
|
@@ -165,7 +165,6 @@ function ChooseAppAndEventSubstep(props) {
|
|||||||
value={getOption(appOptions, step.appKey) || null}
|
value={getOption(appOptions, step.appKey) || null}
|
||||||
onChange={onAppChange}
|
onChange={onAppChange}
|
||||||
data-test="choose-app-autocomplete"
|
data-test="choose-app-autocomplete"
|
||||||
componentsProps={{ popper: { className: 'nowheel' } }}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{step.appKey && (
|
{step.appKey && (
|
||||||
@@ -228,7 +227,6 @@ function ChooseAppAndEventSubstep(props) {
|
|||||||
value={getOption(actionOrTriggerOptions, step.key) || null}
|
value={getOption(actionOrTriggerOptions, step.key) || null}
|
||||||
onChange={onEventChange}
|
onChange={onEventChange}
|
||||||
data-test="choose-event-autocomplete"
|
data-test="choose-event-autocomplete"
|
||||||
componentsProps={{ popper: { className: 'nowheel' } }}
|
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
@@ -240,7 +240,6 @@ function ChooseConnectionSubstep(props) {
|
|||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
loading={isAppConnectionsLoading}
|
loading={isAppConnectionsLoading}
|
||||||
data-test="choose-connection-autocomplete"
|
data-test="choose-connection-autocomplete"
|
||||||
componentsProps={{ popper: { className: 'nowheel' } }}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
@@ -32,11 +32,9 @@ function ControlledAutocomplete(props) {
|
|||||||
...autocompleteProps
|
...autocompleteProps
|
||||||
} = props;
|
} = props;
|
||||||
let dependsOnValues = [];
|
let dependsOnValues = [];
|
||||||
|
|
||||||
if (dependsOn?.length) {
|
if (dependsOn?.length) {
|
||||||
dependsOnValues = watch(dependsOn);
|
dependsOnValues = watch(dependsOn);
|
||||||
}
|
}
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const hasDependencies = dependsOnValues.length;
|
const hasDependencies = dependsOnValues.length;
|
||||||
const allDepsSatisfied = dependsOnValues.every(Boolean);
|
const allDepsSatisfied = dependsOnValues.every(Boolean);
|
||||||
@@ -46,7 +44,6 @@ function ControlledAutocomplete(props) {
|
|||||||
resetField(name);
|
resetField(name);
|
||||||
}
|
}
|
||||||
}, dependsOnValues);
|
}, dependsOnValues);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Controller
|
<Controller
|
||||||
rules={{ required }}
|
rules={{ required }}
|
||||||
|
@@ -47,7 +47,6 @@ const CustomOptions = (props) => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
className="nowheel"
|
|
||||||
>
|
>
|
||||||
<Paper elevation={5} sx={{ width: '100%' }}>
|
<Paper elevation={5} sx={{ width: '100%' }}>
|
||||||
<Tabs
|
<Tabs
|
||||||
|
@@ -8,7 +8,6 @@ import Tooltip from '@mui/material/Tooltip';
|
|||||||
import IconButton from '@mui/material/IconButton';
|
import IconButton from '@mui/material/IconButton';
|
||||||
import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew';
|
import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew';
|
||||||
import Snackbar from '@mui/material/Snackbar';
|
import Snackbar from '@mui/material/Snackbar';
|
||||||
import { ReactFlowProvider } from 'reactflow';
|
|
||||||
|
|
||||||
import { EditorProvider } from 'contexts/Editor';
|
import { EditorProvider } from 'contexts/Editor';
|
||||||
import EditableTypography from 'components/EditableTypography';
|
import EditableTypography from 'components/EditableTypography';
|
||||||
@@ -21,9 +20,6 @@ import * as URLS from 'config/urls';
|
|||||||
import { TopBar } from './style';
|
import { TopBar } from './style';
|
||||||
import useFlow from 'hooks/useFlow';
|
import useFlow from 'hooks/useFlow';
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
import EditorNew from 'components/EditorNew/EditorNew';
|
|
||||||
|
|
||||||
const useNewFlowEditor = process.env.REACT_APP_USE_NEW_FLOW_EDITOR === 'true';
|
|
||||||
|
|
||||||
export default function EditorLayout() {
|
export default function EditorLayout() {
|
||||||
const { flowId } = useParams();
|
const { flowId } = useParams();
|
||||||
@@ -135,28 +131,15 @@ export default function EditorLayout() {
|
|||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
</TopBar>
|
</TopBar>
|
||||||
|
<Stack direction="column" height="100%">
|
||||||
|
<Container maxWidth="md">
|
||||||
|
<EditorProvider value={{ readOnly: !!flow?.active }}>
|
||||||
|
{!flow && !isFlowLoading && 'not found'}
|
||||||
|
|
||||||
{useNewFlowEditor ? (
|
{flow && <Editor flow={flow} />}
|
||||||
<Stack direction="column" height="100%" flexGrow={1}>
|
</EditorProvider>
|
||||||
<Stack direction="column" flexGrow={1}>
|
</Container>
|
||||||
<EditorProvider value={{ readOnly: !!flow?.active }}>
|
</Stack>
|
||||||
<ReactFlowProvider>
|
|
||||||
{!flow && !isFlowLoading && 'not found'}
|
|
||||||
{flow && <EditorNew flow={flow} />}
|
|
||||||
</ReactFlowProvider>
|
|
||||||
</EditorProvider>
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
|
||||||
) : (
|
|
||||||
<Stack direction="column" height="100%">
|
|
||||||
<Container maxWidth="md">
|
|
||||||
<EditorProvider value={{ readOnly: !!flow?.active }}>
|
|
||||||
{!flow && !isFlowLoading && 'not found'}
|
|
||||||
{flow && <Editor flow={flow} />}
|
|
||||||
</EditorProvider>
|
|
||||||
</Container>
|
|
||||||
</Stack>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Snackbar
|
<Snackbar
|
||||||
data-test="flow-cannot-edit-info-snackbar"
|
data-test="flow-cannot-edit-info-snackbar"
|
||||||
|
@@ -1,79 +0,0 @@
|
|||||||
import { EdgeLabelRenderer, getStraightPath } from 'reactflow';
|
|
||||||
import IconButton from '@mui/material/IconButton';
|
|
||||||
import AddIcon from '@mui/icons-material/Add';
|
|
||||||
import { useMutation } from '@apollo/client';
|
|
||||||
import { CREATE_STEP } from 'graphql/mutations/create-step';
|
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
export default function Edge({
|
|
||||||
sourceX,
|
|
||||||
sourceY,
|
|
||||||
targetX,
|
|
||||||
targetY,
|
|
||||||
source,
|
|
||||||
data: { flowId, setCurrentStepId, flowActive, layouted },
|
|
||||||
}) {
|
|
||||||
const [createStep, { loading: creationInProgress }] =
|
|
||||||
useMutation(CREATE_STEP);
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
const [edgePath, labelX, labelY] = getStraightPath({
|
|
||||||
sourceX,
|
|
||||||
sourceY,
|
|
||||||
targetX,
|
|
||||||
targetY,
|
|
||||||
});
|
|
||||||
|
|
||||||
const addStep = async (previousStepId) => {
|
|
||||||
const mutationInput = {
|
|
||||||
previousStep: {
|
|
||||||
id: previousStepId,
|
|
||||||
},
|
|
||||||
flow: {
|
|
||||||
id: flowId,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const createdStep = await createStep({
|
|
||||||
variables: { input: mutationInput },
|
|
||||||
});
|
|
||||||
|
|
||||||
const createdStepId = createdStep.data.createStep.id;
|
|
||||||
setCurrentStepId(createdStepId);
|
|
||||||
await queryClient.invalidateQueries({ queryKey: ['flows', flowId] });
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<EdgeLabelRenderer>
|
|
||||||
<IconButton
|
|
||||||
onClick={() => addStep(source)}
|
|
||||||
color="primary"
|
|
||||||
sx={{
|
|
||||||
position: 'absolute',
|
|
||||||
transform: `translate(-50%, -50%) translate(${labelX}px,${labelY}px)`,
|
|
||||||
pointerEvents: 'all',
|
|
||||||
visibility: layouted ? 'visible' : 'hidden',
|
|
||||||
}}
|
|
||||||
disabled={creationInProgress || flowActive}
|
|
||||||
>
|
|
||||||
<AddIcon />
|
|
||||||
</IconButton>
|
|
||||||
</EdgeLabelRenderer>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Edge.propTypes = {
|
|
||||||
sourceX: PropTypes.number.isRequired,
|
|
||||||
sourceY: PropTypes.number.isRequired,
|
|
||||||
targetX: PropTypes.number.isRequired,
|
|
||||||
targetY: PropTypes.number.isRequired,
|
|
||||||
source: PropTypes.string.isRequired,
|
|
||||||
data: PropTypes.shape({
|
|
||||||
flowId: PropTypes.string.isRequired,
|
|
||||||
setCurrentStepId: PropTypes.func.isRequired,
|
|
||||||
flowActive: PropTypes.bool.isRequired,
|
|
||||||
layouted: PropTypes.bool,
|
|
||||||
}).isRequired,
|
|
||||||
};
|
|
@@ -1,258 +0,0 @@
|
|||||||
import { useEffect, useState, useCallback } from 'react';
|
|
||||||
import { useMutation } from '@apollo/client';
|
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
|
||||||
import { FlowPropType } from 'propTypes/propTypes';
|
|
||||||
import ReactFlow, { useNodesState, useEdgesState, addEdge } from 'reactflow';
|
|
||||||
import 'reactflow/dist/style.css';
|
|
||||||
import { UPDATE_STEP } from 'graphql/mutations/update-step';
|
|
||||||
|
|
||||||
import { useAutoLayout } from './useAutoLayout';
|
|
||||||
import { useScrollBoundries } from './useScrollBoundries';
|
|
||||||
import FlowStepNode from './FlowStepNode/FlowStepNode';
|
|
||||||
import Edge from './Edge/Edge';
|
|
||||||
import InvisibleNode from './InvisibleNode/InvisibleNode';
|
|
||||||
import { EditorWrapper } from './style';
|
|
||||||
|
|
||||||
const nodeTypes = { flowStep: FlowStepNode, invisible: InvisibleNode };
|
|
||||||
|
|
||||||
const edgeTypes = {
|
|
||||||
addNodeEdge: Edge,
|
|
||||||
};
|
|
||||||
|
|
||||||
const INVISIBLE_NODE_ID = 'invisible-node';
|
|
||||||
|
|
||||||
const generateEdgeId = (sourceId, targetId) => `${sourceId}-${targetId}`;
|
|
||||||
|
|
||||||
const EditorNew = ({ flow }) => {
|
|
||||||
const [triggerStep] = flow.steps;
|
|
||||||
const [currentStepId, setCurrentStepId] = useState(triggerStep.id);
|
|
||||||
|
|
||||||
const [updateStep] = useMutation(UPDATE_STEP);
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
|
|
||||||
const [nodes, setNodes, onNodesChange] = useNodesState([]);
|
|
||||||
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
|
|
||||||
useAutoLayout();
|
|
||||||
useScrollBoundries();
|
|
||||||
|
|
||||||
const onConnect = useCallback(
|
|
||||||
(params) => setEdges((eds) => addEdge(params, eds)),
|
|
||||||
[setEdges],
|
|
||||||
);
|
|
||||||
|
|
||||||
const openNextStep = useCallback(
|
|
||||||
(nextStep) => () => {
|
|
||||||
setCurrentStepId(nextStep?.id);
|
|
||||||
},
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
|
|
||||||
const onStepChange = useCallback(
|
|
||||||
async (step) => {
|
|
||||||
const mutationInput = {
|
|
||||||
id: step.id,
|
|
||||||
key: step.key,
|
|
||||||
parameters: step.parameters,
|
|
||||||
connection: {
|
|
||||||
id: step.connection?.id,
|
|
||||||
},
|
|
||||||
flow: {
|
|
||||||
id: flow.id,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if (step.appKey) {
|
|
||||||
mutationInput.appKey = step.appKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
await updateStep({
|
|
||||||
variables: { input: mutationInput },
|
|
||||||
});
|
|
||||||
await queryClient.invalidateQueries({
|
|
||||||
queryKey: ['steps', step.id, 'connection'],
|
|
||||||
});
|
|
||||||
await queryClient.invalidateQueries({ queryKey: ['flows', flow.id] });
|
|
||||||
},
|
|
||||||
[flow.id, updateStep, queryClient],
|
|
||||||
);
|
|
||||||
|
|
||||||
const generateEdges = useCallback((flow, prevEdges) => {
|
|
||||||
const newEdges =
|
|
||||||
flow.steps
|
|
||||||
.map((step, i) => {
|
|
||||||
const sourceId = step.id;
|
|
||||||
const targetId = flow.steps[i + 1]?.id;
|
|
||||||
const edge = prevEdges?.find(
|
|
||||||
(edge) => edge.id === generateEdgeId(sourceId, targetId),
|
|
||||||
);
|
|
||||||
if (targetId) {
|
|
||||||
return {
|
|
||||||
id: generateEdgeId(sourceId, targetId),
|
|
||||||
source: sourceId,
|
|
||||||
target: targetId,
|
|
||||||
type: 'addNodeEdge',
|
|
||||||
data: {
|
|
||||||
flowId: flow.id,
|
|
||||||
flowActive: flow.active,
|
|
||||||
setCurrentStepId,
|
|
||||||
layouted: !!edge,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter((edge) => !!edge) || [];
|
|
||||||
|
|
||||||
const lastStep = flow.steps[flow.steps.length - 1];
|
|
||||||
|
|
||||||
return lastStep
|
|
||||||
? [
|
|
||||||
...newEdges,
|
|
||||||
{
|
|
||||||
id: generateEdgeId(lastStep.id, INVISIBLE_NODE_ID),
|
|
||||||
source: lastStep.id,
|
|
||||||
target: INVISIBLE_NODE_ID,
|
|
||||||
type: 'addNodeEdge',
|
|
||||||
data: {
|
|
||||||
flowId: flow.id,
|
|
||||||
flowActive: flow.active,
|
|
||||||
setCurrentStepId,
|
|
||||||
layouted: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: newEdges;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const generateNodes = useCallback(
|
|
||||||
(flow, prevNodes) => {
|
|
||||||
const newNodes = flow.steps.map((step, index) => {
|
|
||||||
const node = prevNodes?.find(({ id }) => id === step.id);
|
|
||||||
const collapsed = currentStepId !== step.id;
|
|
||||||
return {
|
|
||||||
id: step.id,
|
|
||||||
type: 'flowStep',
|
|
||||||
position: {
|
|
||||||
x: node ? node.position.x : 0,
|
|
||||||
y: node ? node.position.y : 0,
|
|
||||||
},
|
|
||||||
zIndex: collapsed ? 0 : 1,
|
|
||||||
data: {
|
|
||||||
step,
|
|
||||||
index: index,
|
|
||||||
flowId: flow.id,
|
|
||||||
collapsed,
|
|
||||||
openNextStep: openNextStep(flow.steps[index + 1]),
|
|
||||||
onOpen: () => setCurrentStepId(step.id),
|
|
||||||
onClose: () => setCurrentStepId(null),
|
|
||||||
onChange: onStepChange,
|
|
||||||
layouted: !!node,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const prevInvisibleNode = nodes.find((node) => node.type === 'invisible');
|
|
||||||
|
|
||||||
return [
|
|
||||||
...newNodes,
|
|
||||||
{
|
|
||||||
id: INVISIBLE_NODE_ID,
|
|
||||||
type: 'invisible',
|
|
||||||
position: {
|
|
||||||
x: prevInvisibleNode ? prevInvisibleNode.position.x : 0,
|
|
||||||
y: prevInvisibleNode ? prevInvisibleNode.position.y : 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
[currentStepId, nodes, onStepChange, openNextStep],
|
|
||||||
);
|
|
||||||
|
|
||||||
const updateNodesData = useCallback(
|
|
||||||
(steps) => {
|
|
||||||
setNodes((nodes) =>
|
|
||||||
nodes.map((node) => {
|
|
||||||
const step = steps.find((step) => step.id === node.id);
|
|
||||||
if (step) {
|
|
||||||
return { ...node, data: { ...node.data, step: { ...step } } };
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
[setNodes],
|
|
||||||
);
|
|
||||||
|
|
||||||
const updateEdgesData = useCallback(
|
|
||||||
(flow) => {
|
|
||||||
setEdges((edges) =>
|
|
||||||
edges.map((edge) => {
|
|
||||||
return {
|
|
||||||
...edge,
|
|
||||||
data: { ...edge.data, flowId: flow.id, flowActive: flow.active },
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
[setEdges],
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setNodes(
|
|
||||||
nodes.map((node) => {
|
|
||||||
if (node.type === 'flowStep') {
|
|
||||||
const collapsed = currentStepId !== node.data.step.id;
|
|
||||||
return {
|
|
||||||
...node,
|
|
||||||
zIndex: collapsed ? 0 : 1,
|
|
||||||
data: {
|
|
||||||
...node.data,
|
|
||||||
collapsed,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}, [currentStepId]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (flow.steps.length + 1 !== nodes.length) {
|
|
||||||
const newNodes = generateNodes(flow, nodes);
|
|
||||||
const newEdges = generateEdges(flow, edges);
|
|
||||||
|
|
||||||
setNodes(newNodes);
|
|
||||||
setEdges(newEdges);
|
|
||||||
} else {
|
|
||||||
updateNodesData(flow.steps);
|
|
||||||
updateEdgesData(flow);
|
|
||||||
}
|
|
||||||
}, [flow]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<EditorWrapper direction="column">
|
|
||||||
<ReactFlow
|
|
||||||
nodes={nodes}
|
|
||||||
edges={edges}
|
|
||||||
onNodesChange={onNodesChange}
|
|
||||||
onEdgesChange={onEdgesChange}
|
|
||||||
onConnect={onConnect}
|
|
||||||
nodeTypes={nodeTypes}
|
|
||||||
edgeTypes={edgeTypes}
|
|
||||||
panOnScroll
|
|
||||||
panOnScrollMode="vertical"
|
|
||||||
panOnDrag={false}
|
|
||||||
zoomOnScroll={false}
|
|
||||||
zoomOnPinch={false}
|
|
||||||
zoomOnDoubleClick={false}
|
|
||||||
panActivationKeyCode={null}
|
|
||||||
proOptions={{ hideAttribution: true }}
|
|
||||||
/>
|
|
||||||
</EditorWrapper>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
EditorNew.propTypes = {
|
|
||||||
flow: FlowPropType.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default EditorNew;
|
|
@@ -1,72 +0,0 @@
|
|||||||
import { Handle, Position } from 'reactflow';
|
|
||||||
import { Box } from '@mui/material';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import FlowStep from 'components/FlowStep';
|
|
||||||
import { StepPropType } from 'propTypes/propTypes';
|
|
||||||
|
|
||||||
import { NodeWrapper, NodeInnerWrapper } from './style.js';
|
|
||||||
|
|
||||||
function FlowStepNode({
|
|
||||||
data: {
|
|
||||||
step,
|
|
||||||
index,
|
|
||||||
flowId,
|
|
||||||
collapsed,
|
|
||||||
openNextStep,
|
|
||||||
onOpen,
|
|
||||||
onClose,
|
|
||||||
onChange,
|
|
||||||
layouted,
|
|
||||||
},
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<NodeWrapper
|
|
||||||
className="nodrag"
|
|
||||||
sx={{
|
|
||||||
visibility: layouted ? 'visible' : 'hidden',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<NodeInnerWrapper>
|
|
||||||
<Handle
|
|
||||||
type="target"
|
|
||||||
position={Position.Top}
|
|
||||||
isConnectable={false}
|
|
||||||
style={{ visibility: 'hidden' }}
|
|
||||||
/>
|
|
||||||
<FlowStep
|
|
||||||
step={step}
|
|
||||||
index={index + 1}
|
|
||||||
collapsed={collapsed}
|
|
||||||
onOpen={onOpen}
|
|
||||||
onClose={onClose}
|
|
||||||
onChange={onChange}
|
|
||||||
flowId={flowId}
|
|
||||||
onContinue={openNextStep}
|
|
||||||
/>
|
|
||||||
<Handle
|
|
||||||
type="source"
|
|
||||||
position={Position.Bottom}
|
|
||||||
isConnectable={false}
|
|
||||||
style={{ visibility: 'hidden' }}
|
|
||||||
/>
|
|
||||||
</NodeInnerWrapper>
|
|
||||||
</NodeWrapper>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
FlowStepNode.propTypes = {
|
|
||||||
data: PropTypes.shape({
|
|
||||||
step: StepPropType.isRequired,
|
|
||||||
index: PropTypes.number.isRequired,
|
|
||||||
flowId: PropTypes.string.isRequired,
|
|
||||||
collapsed: PropTypes.bool.isRequired,
|
|
||||||
openNextStep: PropTypes.func.isRequired,
|
|
||||||
onOpen: PropTypes.func.isRequired,
|
|
||||||
onClose: PropTypes.func.isRequired,
|
|
||||||
onChange: PropTypes.func.isRequired,
|
|
||||||
layouted: PropTypes.bool.isRequired,
|
|
||||||
}).isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default FlowStepNode;
|
|
@@ -1,14 +0,0 @@
|
|||||||
import { styled } from '@mui/material/styles';
|
|
||||||
import { Box } from '@mui/material';
|
|
||||||
|
|
||||||
export const NodeWrapper = styled(Box)(({ theme }) => ({
|
|
||||||
width: '100vw',
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'center',
|
|
||||||
padding: theme.spacing(0, 2.5),
|
|
||||||
}));
|
|
||||||
|
|
||||||
export const NodeInnerWrapper = styled(Box)(({ theme }) => ({
|
|
||||||
maxWidth: 900,
|
|
||||||
flex: 1,
|
|
||||||
}));
|
|
@@ -1,19 +0,0 @@
|
|||||||
import { Handle, Position } from 'reactflow';
|
|
||||||
import { Box } from '@mui/material';
|
|
||||||
|
|
||||||
// This node is used for adding an edge with add node button after the last flow step node
|
|
||||||
function InvisibleNode() {
|
|
||||||
return (
|
|
||||||
<Box
|
|
||||||
maxWidth={900}
|
|
||||||
width="100vw"
|
|
||||||
className="nodrag"
|
|
||||||
sx={{ visibility: 'hidden' }}
|
|
||||||
>
|
|
||||||
<Handle type="target" position={Position.Top} isConnectable={false} />
|
|
||||||
Invisible node
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default InvisibleNode;
|
|
@@ -1,13 +0,0 @@
|
|||||||
import { Stack } from '@mui/material';
|
|
||||||
import { styled } from '@mui/material/styles';
|
|
||||||
|
|
||||||
export const EditorWrapper = styled(Stack)(({ theme }) => ({
|
|
||||||
flexGrow: 1,
|
|
||||||
'& > div': {
|
|
||||||
flexGrow: 1,
|
|
||||||
},
|
|
||||||
|
|
||||||
'& .react-flow__pane, & .react-flow__node': {
|
|
||||||
cursor: 'auto !important',
|
|
||||||
},
|
|
||||||
}));
|
|
@@ -1,69 +0,0 @@
|
|||||||
import { useCallback, useEffect } from 'react';
|
|
||||||
import Dagre from '@dagrejs/dagre';
|
|
||||||
import { usePrevious } from 'hooks/usePrevious';
|
|
||||||
import { isEqual } from 'lodash';
|
|
||||||
import { useNodesInitialized, useNodes, useReactFlow } from 'reactflow';
|
|
||||||
|
|
||||||
const getLayoutedElements = (nodes, edges) => {
|
|
||||||
const graph = new Dagre.graphlib.Graph().setDefaultEdgeLabel(() => ({}));
|
|
||||||
graph.setGraph({
|
|
||||||
rankdir: 'TB',
|
|
||||||
marginy: 60,
|
|
||||||
ranksep: 64,
|
|
||||||
});
|
|
||||||
edges.forEach((edge) => graph.setEdge(edge.source, edge.target));
|
|
||||||
nodes.forEach((node) => graph.setNode(node.id, node));
|
|
||||||
|
|
||||||
Dagre.layout(graph);
|
|
||||||
|
|
||||||
return {
|
|
||||||
nodes: nodes.map((node) => {
|
|
||||||
const { x, y, width, height } = graph.node(node.id);
|
|
||||||
return {
|
|
||||||
...node,
|
|
||||||
position: { x: x - width / 2, y: y - height / 2 },
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
edges,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useAutoLayout = () => {
|
|
||||||
const nodes = useNodes();
|
|
||||||
const prevNodes = usePrevious(nodes);
|
|
||||||
const nodesInitialized = useNodesInitialized();
|
|
||||||
const { getEdges, setNodes, setEdges } = useReactFlow();
|
|
||||||
|
|
||||||
const onLayout = useCallback(
|
|
||||||
(nodes, edges) => {
|
|
||||||
const layoutedElements = getLayoutedElements(nodes, edges);
|
|
||||||
|
|
||||||
setNodes([
|
|
||||||
...layoutedElements.nodes.map((node) => ({
|
|
||||||
...node,
|
|
||||||
data: { ...node.data, layouted: true },
|
|
||||||
})),
|
|
||||||
]);
|
|
||||||
setEdges([
|
|
||||||
...layoutedElements.edges.map((edge) => ({
|
|
||||||
...edge,
|
|
||||||
data: { ...edge.data, layouted: true },
|
|
||||||
})),
|
|
||||||
]);
|
|
||||||
},
|
|
||||||
[setEdges, setNodes],
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const shouldAutoLayout =
|
|
||||||
nodesInitialized &&
|
|
||||||
!isEqual(
|
|
||||||
nodes.map(({ width, height }) => ({ width, height })),
|
|
||||||
prevNodes.map(({ width, height }) => ({ width, height })),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (shouldAutoLayout) {
|
|
||||||
onLayout(nodes, getEdges());
|
|
||||||
}
|
|
||||||
}, [nodes]);
|
|
||||||
};
|
|
@@ -1,13 +0,0 @@
|
|||||||
import { useEffect } from 'react';
|
|
||||||
import { useViewport, useReactFlow } from 'reactflow';
|
|
||||||
|
|
||||||
export const useScrollBoundries = () => {
|
|
||||||
const { setViewport } = useReactFlow();
|
|
||||||
const { x, y, zoom } = useViewport();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (y > 0) {
|
|
||||||
setViewport({ x, y: 0, zoom });
|
|
||||||
}
|
|
||||||
}, [y]);
|
|
||||||
};
|
|
@@ -28,12 +28,9 @@ function ContextMenu(props) {
|
|||||||
variables: { input: { id: flowId } },
|
variables: { input: { id: flowId } },
|
||||||
});
|
});
|
||||||
|
|
||||||
if (appKey) {
|
await queryClient.invalidateQueries({
|
||||||
await queryClient.invalidateQueries({
|
queryKey: ['apps', appKey, 'flows'],
|
||||||
queryKey: ['apps', appKey, 'flows'],
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
enqueueSnackbar(formatMessage('flow.successfullyDuplicated'), {
|
enqueueSnackbar(formatMessage('flow.successfullyDuplicated'), {
|
||||||
variant: 'success',
|
variant: 'success',
|
||||||
SnackbarProps: {
|
SnackbarProps: {
|
||||||
@@ -59,12 +56,9 @@ function ContextMenu(props) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (appKey) {
|
await queryClient.invalidateQueries({
|
||||||
await queryClient.invalidateQueries({
|
queryKey: ['apps', appKey, 'flows'],
|
||||||
queryKey: ['apps', appKey, 'flows'],
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
enqueueSnackbar(formatMessage('flow.successfullyDeleted'), {
|
enqueueSnackbar(formatMessage('flow.successfullyDeleted'), {
|
||||||
variant: 'success',
|
variant: 'success',
|
||||||
});
|
});
|
||||||
@@ -116,7 +110,7 @@ ContextMenu.propTypes = {
|
|||||||
]).isRequired,
|
]).isRequired,
|
||||||
onDeleteFlow: PropTypes.func,
|
onDeleteFlow: PropTypes.func,
|
||||||
onDuplicateFlow: PropTypes.func,
|
onDuplicateFlow: PropTypes.func,
|
||||||
appKey: PropTypes.string,
|
appKey: PropTypes.string.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ContextMenu;
|
export default ContextMenu;
|
||||||
|
@@ -38,24 +38,20 @@ function FlowRow(props) {
|
|||||||
const contextButtonRef = React.useRef(null);
|
const contextButtonRef = React.useRef(null);
|
||||||
const [anchorEl, setAnchorEl] = React.useState(null);
|
const [anchorEl, setAnchorEl] = React.useState(null);
|
||||||
const { flow, onDuplicateFlow, onDeleteFlow, appKey } = props;
|
const { flow, onDuplicateFlow, onDeleteFlow, appKey } = props;
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setAnchorEl(null);
|
setAnchorEl(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onContextMenuClick = (event) => {
|
const onContextMenuClick = (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.nativeEvent.stopImmediatePropagation();
|
event.nativeEvent.stopImmediatePropagation();
|
||||||
setAnchorEl(contextButtonRef.current);
|
setAnchorEl(contextButtonRef.current);
|
||||||
};
|
};
|
||||||
|
|
||||||
const createdAt = DateTime.fromMillis(parseInt(flow.createdAt, 10));
|
const createdAt = DateTime.fromMillis(parseInt(flow.createdAt, 10));
|
||||||
const updatedAt = DateTime.fromMillis(parseInt(flow.updatedAt, 10));
|
const updatedAt = DateTime.fromMillis(parseInt(flow.updatedAt, 10));
|
||||||
const isUpdated = updatedAt > createdAt;
|
const isUpdated = updatedAt > createdAt;
|
||||||
const relativeCreatedAt = createdAt.toRelative();
|
const relativeCreatedAt = createdAt.toRelative();
|
||||||
const relativeUpdatedAt = updatedAt.toRelative();
|
const relativeUpdatedAt = updatedAt.toRelative();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Card sx={{ mb: 1 }} data-test="flow-row">
|
<Card sx={{ mb: 1 }} data-test="flow-row">
|
||||||
@@ -131,7 +127,7 @@ FlowRow.propTypes = {
|
|||||||
flow: FlowPropType.isRequired,
|
flow: FlowPropType.isRequired,
|
||||||
onDeleteFlow: PropTypes.func,
|
onDeleteFlow: PropTypes.func,
|
||||||
onDuplicateFlow: PropTypes.func,
|
onDuplicateFlow: PropTypes.func,
|
||||||
appKey: PropTypes.string,
|
appKey: PropTypes.string.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FlowRow;
|
export default FlowRow;
|
||||||
|
@@ -80,7 +80,6 @@ export default function InputCreator(props) {
|
|||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
showOptionValue={showOptionValue}
|
showOptionValue={showOptionValue}
|
||||||
shouldUnregister={shouldUnregister}
|
shouldUnregister={shouldUnregister}
|
||||||
componentsProps={{ popper: { className: 'nowheel' } }}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@@ -17,7 +17,6 @@ import { StepExecutionsContext } from 'contexts/StepExecutions';
|
|||||||
import Popper from './Popper';
|
import Popper from './Popper';
|
||||||
import { processStepWithExecutions } from './data';
|
import { processStepWithExecutions } from './data';
|
||||||
import { ChildrenWrapper, FakeInput, InputLabelWrapper } from './style';
|
import { ChildrenWrapper, FakeInput, InputLabelWrapper } from './style';
|
||||||
|
|
||||||
const PowerInput = (props) => {
|
const PowerInput = (props) => {
|
||||||
const { control } = useFormContext();
|
const { control } = useFormContext();
|
||||||
const {
|
const {
|
||||||
@@ -32,41 +31,33 @@ const PowerInput = (props) => {
|
|||||||
} = props;
|
} = props;
|
||||||
const priorStepsWithExecutions = React.useContext(StepExecutionsContext);
|
const priorStepsWithExecutions = React.useContext(StepExecutionsContext);
|
||||||
const editorRef = React.useRef(null);
|
const editorRef = React.useRef(null);
|
||||||
|
|
||||||
const renderElement = React.useCallback(
|
const renderElement = React.useCallback(
|
||||||
(props) => <Element {...props} />,
|
(props) => <Element {...props} />,
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
const [editor] = React.useState(() => customizeEditor(createEditor()));
|
const [editor] = React.useState(() => customizeEditor(createEditor()));
|
||||||
|
|
||||||
const [showVariableSuggestions, setShowVariableSuggestions] =
|
const [showVariableSuggestions, setShowVariableSuggestions] =
|
||||||
React.useState(false);
|
React.useState(false);
|
||||||
|
|
||||||
const disappearSuggestionsOnShift = (event) => {
|
const disappearSuggestionsOnShift = (event) => {
|
||||||
if (event.code === 'Tab') {
|
if (event.code === 'Tab') {
|
||||||
setShowVariableSuggestions(false);
|
setShowVariableSuggestions(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const stepsWithVariables = React.useMemo(() => {
|
const stepsWithVariables = React.useMemo(() => {
|
||||||
return processStepWithExecutions(priorStepsWithExecutions);
|
return processStepWithExecutions(priorStepsWithExecutions);
|
||||||
}, [priorStepsWithExecutions]);
|
}, [priorStepsWithExecutions]);
|
||||||
|
|
||||||
const handleBlur = React.useCallback(
|
const handleBlur = React.useCallback(
|
||||||
(value) => {
|
(value) => {
|
||||||
onBlur?.(value);
|
onBlur?.(value);
|
||||||
},
|
},
|
||||||
[onBlur],
|
[onBlur],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleVariableSuggestionClick = React.useCallback(
|
const handleVariableSuggestionClick = React.useCallback(
|
||||||
(variable) => {
|
(variable) => {
|
||||||
insertVariable(editor, variable, stepsWithVariables);
|
insertVariable(editor, variable, stepsWithVariables);
|
||||||
},
|
},
|
||||||
[stepsWithVariables],
|
[stepsWithVariables],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Controller
|
<Controller
|
||||||
rules={{ required }}
|
rules={{ required }}
|
||||||
@@ -136,7 +127,6 @@ const PowerInput = (props) => {
|
|||||||
anchorEl={editorRef.current}
|
anchorEl={editorRef.current}
|
||||||
data={stepsWithVariables}
|
data={stepsWithVariables}
|
||||||
onSuggestionClick={handleVariableSuggestionClick}
|
onSuggestionClick={handleVariableSuggestionClick}
|
||||||
className="nowheel"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FormHelperText variant="outlined">{description}</FormHelperText>
|
<FormHelperText variant="outlined">{description}</FormHelperText>
|
||||||
|
@@ -1,9 +0,0 @@
|
|||||||
import { useEffect, useRef } from "react";
|
|
||||||
|
|
||||||
export const usePrevious = (value) => {
|
|
||||||
const ref = useRef();
|
|
||||||
useEffect(() => {
|
|
||||||
ref.current = value;
|
|
||||||
});
|
|
||||||
return ref.current;
|
|
||||||
};
|
|
@@ -3,7 +3,7 @@ services:
|
|||||||
name: automatisch-main
|
name: automatisch-main
|
||||||
env: docker
|
env: docker
|
||||||
dockerfilePath: ./docker/Dockerfile
|
dockerfilePath: ./docker/Dockerfile
|
||||||
dockerContext: .
|
dockerContext: ./docker
|
||||||
repo: https://github.com/automatisch/automatisch
|
repo: https://github.com/automatisch/automatisch
|
||||||
autoDeploy: false
|
autoDeploy: false
|
||||||
envVars:
|
envVars:
|
||||||
@@ -47,7 +47,7 @@ services:
|
|||||||
name: automatisch-worker
|
name: automatisch-worker
|
||||||
env: docker
|
env: docker
|
||||||
dockerfilePath: ./docker/Dockerfile
|
dockerfilePath: ./docker/Dockerfile
|
||||||
dockerContext: .
|
dockerContext: ./docker
|
||||||
repo: https://github.com/automatisch/automatisch
|
repo: https://github.com/automatisch/automatisch
|
||||||
autoDeploy: false
|
autoDeploy: false
|
||||||
envVars:
|
envVars:
|
||||||
|
460
yarn.lock
460
yarn.lock
@@ -170,6 +170,52 @@
|
|||||||
tslib "^2.3.0"
|
tslib "^2.3.0"
|
||||||
zen-observable-ts "~1.1.0"
|
zen-observable-ts "~1.1.0"
|
||||||
|
|
||||||
|
"@atproto/api@^0.12.13":
|
||||||
|
version "0.12.13"
|
||||||
|
resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.13.tgz#269d6c57ea894e23f20b28bd3cbfed944bd28528"
|
||||||
|
integrity sha512-pRSID6w8AUiZJoCxgctMPRTSGVFHq7wphAnxEbRLBP3OQ1g+BRZUcqFw+e+17Pd3wrc8VImjiD4HCWtCJvCx3w==
|
||||||
|
dependencies:
|
||||||
|
"@atproto/common-web" "^0.3.0"
|
||||||
|
"@atproto/lexicon" "^0.4.0"
|
||||||
|
"@atproto/syntax" "^0.3.0"
|
||||||
|
"@atproto/xrpc" "^0.5.0"
|
||||||
|
multiformats "^9.9.0"
|
||||||
|
tlds "^1.234.0"
|
||||||
|
|
||||||
|
"@atproto/common-web@^0.3.0":
|
||||||
|
version "0.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@atproto/common-web/-/common-web-0.3.0.tgz#36da8c2c31d8cf8a140c3c8f03223319bf4430bb"
|
||||||
|
integrity sha512-67VnV6JJyX+ZWyjV7xFQMypAgDmjVaR9ZCuU/QW+mqlqI7fex2uL4Fv+7/jHadgzhuJHVd6OHOvNn0wR5WZYtA==
|
||||||
|
dependencies:
|
||||||
|
graphemer "^1.4.0"
|
||||||
|
multiformats "^9.9.0"
|
||||||
|
uint8arrays "3.0.0"
|
||||||
|
zod "^3.21.4"
|
||||||
|
|
||||||
|
"@atproto/lexicon@^0.4.0":
|
||||||
|
version "0.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.4.0.tgz#63e8829945d80c25524882caa8ed27b1151cc576"
|
||||||
|
integrity sha512-RvCBKdSI4M8qWm5uTNz1z3R2yIvIhmOsMuleOj8YR6BwRD+QbtUBy3l+xQ7iXf4M5fdfJFxaUNa6Ty0iRwdKqQ==
|
||||||
|
dependencies:
|
||||||
|
"@atproto/common-web" "^0.3.0"
|
||||||
|
"@atproto/syntax" "^0.3.0"
|
||||||
|
iso-datestring-validator "^2.2.2"
|
||||||
|
multiformats "^9.9.0"
|
||||||
|
zod "^3.21.4"
|
||||||
|
|
||||||
|
"@atproto/syntax@^0.3.0":
|
||||||
|
version "0.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@atproto/syntax/-/syntax-0.3.0.tgz#fafa2dbea9add37253005cb663e7373e05e618b3"
|
||||||
|
integrity sha512-Weq0ZBxffGHDXHl9U7BQc2BFJi/e23AL+k+i5+D9hUq/bzT4yjGsrCejkjq0xt82xXDjmhhvQSZ0LqxyZ5woxA==
|
||||||
|
|
||||||
|
"@atproto/xrpc@^0.5.0":
|
||||||
|
version "0.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.5.0.tgz#dacbfd8f7b13f0ab5bd56f8fdd4b460e132a6032"
|
||||||
|
integrity sha512-swu+wyOLvYW4l3n+VAuJbHcPcES+tin2Lsrp8Bw5aIXIICiuFn1YMFlwK9JwVUzTH21Py1s1nHEjr4CJeElJog==
|
||||||
|
dependencies:
|
||||||
|
"@atproto/lexicon" "^0.4.0"
|
||||||
|
zod "^3.21.4"
|
||||||
|
|
||||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.8.3":
|
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.8.3":
|
||||||
version "7.16.7"
|
version "7.16.7"
|
||||||
resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz"
|
resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz"
|
||||||
@@ -1455,18 +1501,6 @@
|
|||||||
enabled "2.0.x"
|
enabled "2.0.x"
|
||||||
kuler "^2.0.0"
|
kuler "^2.0.0"
|
||||||
|
|
||||||
"@dagrejs/dagre@^1.1.2":
|
|
||||||
version "1.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@dagrejs/dagre/-/dagre-1.1.2.tgz#5ec339979447091f48d2144deed8c70dfadae374"
|
|
||||||
integrity sha512-F09dphqvHsbe/6C2t2unbmpr5q41BNPEfJCdn8Z7aEBpVSy/zFQ/b4SWsweQjWNsYMDvE2ffNUN8X0CeFsEGNw==
|
|
||||||
dependencies:
|
|
||||||
"@dagrejs/graphlib" "2.2.2"
|
|
||||||
|
|
||||||
"@dagrejs/graphlib@2.2.2":
|
|
||||||
version "2.2.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@dagrejs/graphlib/-/graphlib-2.2.2.tgz#74154d5cb880a23b4fae71034a09b4b5aef06feb"
|
|
||||||
integrity sha512-CbyGpCDKsiTg/wuk79S7Muoj8mghDGAESWGxcSyhHX5jD35vYMBZochYVFzlHxynpE9unpu6O+4ZuhrLxASsOg==
|
|
||||||
|
|
||||||
"@docsearch/css@3.2.1", "@docsearch/css@^3.2.1":
|
"@docsearch/css@3.2.1", "@docsearch/css@^3.2.1":
|
||||||
version "3.2.1"
|
version "3.2.1"
|
||||||
resolved "https://registry.npmjs.org/@docsearch/css/-/css-3.2.1.tgz"
|
resolved "https://registry.npmjs.org/@docsearch/css/-/css-3.2.1.tgz"
|
||||||
@@ -3345,72 +3379,6 @@
|
|||||||
resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz"
|
resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz"
|
||||||
integrity sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==
|
integrity sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==
|
||||||
|
|
||||||
"@reactflow/background@11.3.12":
|
|
||||||
version "11.3.12"
|
|
||||||
resolved "https://registry.yarnpkg.com/@reactflow/background/-/background-11.3.12.tgz#9c9491cce4659bae13074fcdb48ac25664879d3f"
|
|
||||||
integrity sha512-jBuWVb43JQy5h4WOS7G0PU8voGTEJNA+qDmx8/jyBtrjbasTesLNfQvboTGjnQYYiJco6mw5vrtQItAJDNoIqw==
|
|
||||||
dependencies:
|
|
||||||
"@reactflow/core" "11.11.2"
|
|
||||||
classcat "^5.0.3"
|
|
||||||
zustand "^4.4.1"
|
|
||||||
|
|
||||||
"@reactflow/controls@11.2.12":
|
|
||||||
version "11.2.12"
|
|
||||||
resolved "https://registry.yarnpkg.com/@reactflow/controls/-/controls-11.2.12.tgz#85e2aa5de17e2af28a5ecf6a75bb9c828a20640b"
|
|
||||||
integrity sha512-L9F3+avFRShoprdT+5oOijm5gVsz2rqWCXBzOAgD923L1XFGIspdiHLLf8IlPGsT+mfl0GxbptZhaEeEzl1e3g==
|
|
||||||
dependencies:
|
|
||||||
"@reactflow/core" "11.11.2"
|
|
||||||
classcat "^5.0.3"
|
|
||||||
zustand "^4.4.1"
|
|
||||||
|
|
||||||
"@reactflow/core@11.11.2":
|
|
||||||
version "11.11.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@reactflow/core/-/core-11.11.2.tgz#c62f78297bda9d2e86a12228617ec3f91fbd4b22"
|
|
||||||
integrity sha512-+GfgyskweL1PsgRSguUwfrT2eDotlFgaKfDLm7x0brdzzPJY2qbCzVetaxedaiJmIli3817iYbILvE9qLKwbRA==
|
|
||||||
dependencies:
|
|
||||||
"@types/d3" "^7.4.0"
|
|
||||||
"@types/d3-drag" "^3.0.1"
|
|
||||||
"@types/d3-selection" "^3.0.3"
|
|
||||||
"@types/d3-zoom" "^3.0.1"
|
|
||||||
classcat "^5.0.3"
|
|
||||||
d3-drag "^3.0.0"
|
|
||||||
d3-selection "^3.0.0"
|
|
||||||
d3-zoom "^3.0.0"
|
|
||||||
zustand "^4.4.1"
|
|
||||||
|
|
||||||
"@reactflow/minimap@11.7.12":
|
|
||||||
version "11.7.12"
|
|
||||||
resolved "https://registry.yarnpkg.com/@reactflow/minimap/-/minimap-11.7.12.tgz#6b2fc671ee17e37ccd3bc038ae8d2121d0ce6291"
|
|
||||||
integrity sha512-SRDU77c2PCF54PV/MQfkz7VOW46q7V1LZNOQlXAp7dkNyAOI6R+tb9qBUtUJOvILB+TCN6pRfD9fQ+2T99bW3Q==
|
|
||||||
dependencies:
|
|
||||||
"@reactflow/core" "11.11.2"
|
|
||||||
"@types/d3-selection" "^3.0.3"
|
|
||||||
"@types/d3-zoom" "^3.0.1"
|
|
||||||
classcat "^5.0.3"
|
|
||||||
d3-selection "^3.0.0"
|
|
||||||
d3-zoom "^3.0.0"
|
|
||||||
zustand "^4.4.1"
|
|
||||||
|
|
||||||
"@reactflow/node-resizer@2.2.12":
|
|
||||||
version "2.2.12"
|
|
||||||
resolved "https://registry.yarnpkg.com/@reactflow/node-resizer/-/node-resizer-2.2.12.tgz#df82a7dfba883afea6a01a9c8210008a1ddba01f"
|
|
||||||
integrity sha512-6LHJGuI1zHyRrZHw5gGlVLIWnvVxid9WIqw8FMFSg+oF2DuS3pAPwSoZwypy7W22/gDNl9eD1Dcl/OtFtDFQ+w==
|
|
||||||
dependencies:
|
|
||||||
"@reactflow/core" "11.11.2"
|
|
||||||
classcat "^5.0.4"
|
|
||||||
d3-drag "^3.0.0"
|
|
||||||
d3-selection "^3.0.0"
|
|
||||||
zustand "^4.4.1"
|
|
||||||
|
|
||||||
"@reactflow/node-toolbar@1.3.12":
|
|
||||||
version "1.3.12"
|
|
||||||
resolved "https://registry.yarnpkg.com/@reactflow/node-toolbar/-/node-toolbar-1.3.12.tgz#89e7aa9d34b6213bb5e64c344d4e2e3cb7af3163"
|
|
||||||
integrity sha512-4kJRvNna/E3y2MZW9/80wTKwkhw4pLJiz3D5eQrD13XcmojSb1rArO9CiwyrI+rMvs5gn6NlCFB4iN1F+Q+lxQ==
|
|
||||||
dependencies:
|
|
||||||
"@reactflow/core" "11.11.2"
|
|
||||||
classcat "^5.0.3"
|
|
||||||
zustand "^4.4.1"
|
|
||||||
|
|
||||||
"@rollup/plugin-babel@^5.2.0":
|
"@rollup/plugin-babel@^5.2.0":
|
||||||
version "5.3.0"
|
version "5.3.0"
|
||||||
resolved "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.0.tgz"
|
resolved "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.0.tgz"
|
||||||
@@ -3901,216 +3869,6 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/d3-array@*":
|
|
||||||
version "3.2.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.1.tgz#1f6658e3d2006c4fceac53fde464166859f8b8c5"
|
|
||||||
integrity sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==
|
|
||||||
|
|
||||||
"@types/d3-axis@*":
|
|
||||||
version "3.0.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-axis/-/d3-axis-3.0.6.tgz#e760e5765b8188b1defa32bc8bb6062f81e4c795"
|
|
||||||
integrity sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==
|
|
||||||
dependencies:
|
|
||||||
"@types/d3-selection" "*"
|
|
||||||
|
|
||||||
"@types/d3-brush@*":
|
|
||||||
version "3.0.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-brush/-/d3-brush-3.0.6.tgz#c2f4362b045d472e1b186cdbec329ba52bdaee6c"
|
|
||||||
integrity sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==
|
|
||||||
dependencies:
|
|
||||||
"@types/d3-selection" "*"
|
|
||||||
|
|
||||||
"@types/d3-chord@*":
|
|
||||||
version "3.0.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-chord/-/d3-chord-3.0.6.tgz#1706ca40cf7ea59a0add8f4456efff8f8775793d"
|
|
||||||
integrity sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==
|
|
||||||
|
|
||||||
"@types/d3-color@*":
|
|
||||||
version "3.1.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.3.tgz#368c961a18de721da8200e80bf3943fb53136af2"
|
|
||||||
integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==
|
|
||||||
|
|
||||||
"@types/d3-contour@*":
|
|
||||||
version "3.0.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-contour/-/d3-contour-3.0.6.tgz#9ada3fa9c4d00e3a5093fed0356c7ab929604231"
|
|
||||||
integrity sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==
|
|
||||||
dependencies:
|
|
||||||
"@types/d3-array" "*"
|
|
||||||
"@types/geojson" "*"
|
|
||||||
|
|
||||||
"@types/d3-delaunay@*":
|
|
||||||
version "6.0.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz#185c1a80cc807fdda2a3fe960f7c11c4a27952e1"
|
|
||||||
integrity sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==
|
|
||||||
|
|
||||||
"@types/d3-dispatch@*":
|
|
||||||
version "3.0.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz#096efdf55eb97480e3f5621ff9a8da552f0961e7"
|
|
||||||
integrity sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==
|
|
||||||
|
|
||||||
"@types/d3-drag@*", "@types/d3-drag@^3.0.1":
|
|
||||||
version "3.0.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-drag/-/d3-drag-3.0.7.tgz#b13aba8b2442b4068c9a9e6d1d82f8bcea77fc02"
|
|
||||||
integrity sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==
|
|
||||||
dependencies:
|
|
||||||
"@types/d3-selection" "*"
|
|
||||||
|
|
||||||
"@types/d3-dsv@*":
|
|
||||||
version "3.0.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-dsv/-/d3-dsv-3.0.7.tgz#0a351f996dc99b37f4fa58b492c2d1c04e3dac17"
|
|
||||||
integrity sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==
|
|
||||||
|
|
||||||
"@types/d3-ease@*":
|
|
||||||
version "3.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.2.tgz#e28db1bfbfa617076f7770dd1d9a48eaa3b6c51b"
|
|
||||||
integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==
|
|
||||||
|
|
||||||
"@types/d3-fetch@*":
|
|
||||||
version "3.0.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-fetch/-/d3-fetch-3.0.7.tgz#c04a2b4f23181aa376f30af0283dbc7b3b569980"
|
|
||||||
integrity sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==
|
|
||||||
dependencies:
|
|
||||||
"@types/d3-dsv" "*"
|
|
||||||
|
|
||||||
"@types/d3-force@*":
|
|
||||||
version "3.0.9"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-force/-/d3-force-3.0.9.tgz#dd96ccefba4386fe4ff36b8e4ee4e120c21fcf29"
|
|
||||||
integrity sha512-IKtvyFdb4Q0LWna6ymywQsEYjK/94SGhPrMfEr1TIc5OBeziTi+1jcCvttts8e0UWZIxpasjnQk9MNk/3iS+kA==
|
|
||||||
|
|
||||||
"@types/d3-format@*":
|
|
||||||
version "3.0.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-format/-/d3-format-3.0.4.tgz#b1e4465644ddb3fdf3a263febb240a6cd616de90"
|
|
||||||
integrity sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==
|
|
||||||
|
|
||||||
"@types/d3-geo@*":
|
|
||||||
version "3.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-3.1.0.tgz#b9e56a079449174f0a2c8684a9a4df3f60522440"
|
|
||||||
integrity sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==
|
|
||||||
dependencies:
|
|
||||||
"@types/geojson" "*"
|
|
||||||
|
|
||||||
"@types/d3-hierarchy@*":
|
|
||||||
version "3.1.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz#6023fb3b2d463229f2d680f9ac4b47466f71f17b"
|
|
||||||
integrity sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==
|
|
||||||
|
|
||||||
"@types/d3-interpolate@*":
|
|
||||||
version "3.0.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz#412b90e84870285f2ff8a846c6eb60344f12a41c"
|
|
||||||
integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==
|
|
||||||
dependencies:
|
|
||||||
"@types/d3-color" "*"
|
|
||||||
|
|
||||||
"@types/d3-path@*":
|
|
||||||
version "3.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.1.0.tgz#2b907adce762a78e98828f0b438eaca339ae410a"
|
|
||||||
integrity sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==
|
|
||||||
|
|
||||||
"@types/d3-polygon@*":
|
|
||||||
version "3.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-polygon/-/d3-polygon-3.0.2.tgz#dfae54a6d35d19e76ac9565bcb32a8e54693189c"
|
|
||||||
integrity sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==
|
|
||||||
|
|
||||||
"@types/d3-quadtree@*":
|
|
||||||
version "3.0.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz#d4740b0fe35b1c58b66e1488f4e7ed02952f570f"
|
|
||||||
integrity sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==
|
|
||||||
|
|
||||||
"@types/d3-random@*":
|
|
||||||
version "3.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-random/-/d3-random-3.0.3.tgz#ed995c71ecb15e0cd31e22d9d5d23942e3300cfb"
|
|
||||||
integrity sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==
|
|
||||||
|
|
||||||
"@types/d3-scale-chromatic@*":
|
|
||||||
version "3.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz#fc0db9c10e789c351f4c42d96f31f2e4df8f5644"
|
|
||||||
integrity sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==
|
|
||||||
|
|
||||||
"@types/d3-scale@*":
|
|
||||||
version "4.0.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.8.tgz#d409b5f9dcf63074464bf8ddfb8ee5a1f95945bb"
|
|
||||||
integrity sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==
|
|
||||||
dependencies:
|
|
||||||
"@types/d3-time" "*"
|
|
||||||
|
|
||||||
"@types/d3-selection@*", "@types/d3-selection@^3.0.3":
|
|
||||||
version "3.0.10"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-3.0.10.tgz#98cdcf986d0986de6912b5892e7c015a95ca27fe"
|
|
||||||
integrity sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==
|
|
||||||
|
|
||||||
"@types/d3-shape@*":
|
|
||||||
version "3.1.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.6.tgz#65d40d5a548f0a023821773e39012805e6e31a72"
|
|
||||||
integrity sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==
|
|
||||||
dependencies:
|
|
||||||
"@types/d3-path" "*"
|
|
||||||
|
|
||||||
"@types/d3-time-format@*":
|
|
||||||
version "4.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-time-format/-/d3-time-format-4.0.3.tgz#d6bc1e6b6a7db69cccfbbdd4c34b70632d9e9db2"
|
|
||||||
integrity sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==
|
|
||||||
|
|
||||||
"@types/d3-time@*":
|
|
||||||
version "3.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.3.tgz#3c186bbd9d12b9d84253b6be6487ca56b54f88be"
|
|
||||||
integrity sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==
|
|
||||||
|
|
||||||
"@types/d3-timer@*":
|
|
||||||
version "3.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.2.tgz#70bbda77dc23aa727413e22e214afa3f0e852f70"
|
|
||||||
integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==
|
|
||||||
|
|
||||||
"@types/d3-transition@*":
|
|
||||||
version "3.0.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-transition/-/d3-transition-3.0.8.tgz#677707f5eed5b24c66a1918cde05963021351a8f"
|
|
||||||
integrity sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ==
|
|
||||||
dependencies:
|
|
||||||
"@types/d3-selection" "*"
|
|
||||||
|
|
||||||
"@types/d3-zoom@*", "@types/d3-zoom@^3.0.1":
|
|
||||||
version "3.0.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3-zoom/-/d3-zoom-3.0.8.tgz#dccb32d1c56b1e1c6e0f1180d994896f038bc40b"
|
|
||||||
integrity sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==
|
|
||||||
dependencies:
|
|
||||||
"@types/d3-interpolate" "*"
|
|
||||||
"@types/d3-selection" "*"
|
|
||||||
|
|
||||||
"@types/d3@^7.4.0":
|
|
||||||
version "7.4.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/d3/-/d3-7.4.3.tgz#d4550a85d08f4978faf0a4c36b848c61eaac07e2"
|
|
||||||
integrity sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==
|
|
||||||
dependencies:
|
|
||||||
"@types/d3-array" "*"
|
|
||||||
"@types/d3-axis" "*"
|
|
||||||
"@types/d3-brush" "*"
|
|
||||||
"@types/d3-chord" "*"
|
|
||||||
"@types/d3-color" "*"
|
|
||||||
"@types/d3-contour" "*"
|
|
||||||
"@types/d3-delaunay" "*"
|
|
||||||
"@types/d3-dispatch" "*"
|
|
||||||
"@types/d3-drag" "*"
|
|
||||||
"@types/d3-dsv" "*"
|
|
||||||
"@types/d3-ease" "*"
|
|
||||||
"@types/d3-fetch" "*"
|
|
||||||
"@types/d3-force" "*"
|
|
||||||
"@types/d3-format" "*"
|
|
||||||
"@types/d3-geo" "*"
|
|
||||||
"@types/d3-hierarchy" "*"
|
|
||||||
"@types/d3-interpolate" "*"
|
|
||||||
"@types/d3-path" "*"
|
|
||||||
"@types/d3-polygon" "*"
|
|
||||||
"@types/d3-quadtree" "*"
|
|
||||||
"@types/d3-random" "*"
|
|
||||||
"@types/d3-scale" "*"
|
|
||||||
"@types/d3-scale-chromatic" "*"
|
|
||||||
"@types/d3-selection" "*"
|
|
||||||
"@types/d3-shape" "*"
|
|
||||||
"@types/d3-time" "*"
|
|
||||||
"@types/d3-time-format" "*"
|
|
||||||
"@types/d3-timer" "*"
|
|
||||||
"@types/d3-transition" "*"
|
|
||||||
"@types/d3-zoom" "*"
|
|
||||||
|
|
||||||
"@types/debug@^4.1.7":
|
"@types/debug@^4.1.7":
|
||||||
version "4.1.8"
|
version "4.1.8"
|
||||||
resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz"
|
resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz"
|
||||||
@@ -4201,11 +3959,6 @@
|
|||||||
"@types/qs" "*"
|
"@types/qs" "*"
|
||||||
"@types/serve-static" "*"
|
"@types/serve-static" "*"
|
||||||
|
|
||||||
"@types/geojson@*":
|
|
||||||
version "7946.0.14"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.14.tgz#319b63ad6df705ee2a65a73ef042c8271e696613"
|
|
||||||
integrity sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==
|
|
||||||
|
|
||||||
"@types/graceful-fs@^4.1.2":
|
"@types/graceful-fs@^4.1.2":
|
||||||
version "4.1.5"
|
version "4.1.5"
|
||||||
resolved "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz"
|
resolved "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz"
|
||||||
@@ -6337,11 +6090,6 @@ cjs-module-lexer@^1.0.0:
|
|||||||
resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz"
|
resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz"
|
||||||
integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==
|
integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==
|
||||||
|
|
||||||
classcat@^5.0.3, classcat@^5.0.4:
|
|
||||||
version "5.0.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/classcat/-/classcat-5.0.5.tgz#8c209f359a93ac302404a10161b501eba9c09c77"
|
|
||||||
integrity sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==
|
|
||||||
|
|
||||||
clean-css@^5.2.2:
|
clean-css@^5.2.2:
|
||||||
version "5.2.2"
|
version "5.2.2"
|
||||||
resolved "https://registry.npmjs.org/clean-css/-/clean-css-5.2.2.tgz"
|
resolved "https://registry.npmjs.org/clean-css/-/clean-css-5.2.2.tgz"
|
||||||
@@ -7127,68 +6875,6 @@ csstype@^3.1.1:
|
|||||||
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz"
|
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz"
|
||||||
integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==
|
integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==
|
||||||
|
|
||||||
"d3-color@1 - 3":
|
|
||||||
version "3.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2"
|
|
||||||
integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==
|
|
||||||
|
|
||||||
"d3-dispatch@1 - 3":
|
|
||||||
version "3.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-3.0.1.tgz#5fc75284e9c2375c36c839411a0cf550cbfc4d5e"
|
|
||||||
integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==
|
|
||||||
|
|
||||||
"d3-drag@2 - 3", d3-drag@^3.0.0:
|
|
||||||
version "3.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-3.0.0.tgz#994aae9cd23c719f53b5e10e3a0a6108c69607ba"
|
|
||||||
integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==
|
|
||||||
dependencies:
|
|
||||||
d3-dispatch "1 - 3"
|
|
||||||
d3-selection "3"
|
|
||||||
|
|
||||||
"d3-ease@1 - 3":
|
|
||||||
version "3.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4"
|
|
||||||
integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==
|
|
||||||
|
|
||||||
"d3-interpolate@1 - 3":
|
|
||||||
version "3.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d"
|
|
||||||
integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==
|
|
||||||
dependencies:
|
|
||||||
d3-color "1 - 3"
|
|
||||||
|
|
||||||
"d3-selection@2 - 3", d3-selection@3, d3-selection@^3.0.0:
|
|
||||||
version "3.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-3.0.0.tgz#c25338207efa72cc5b9bd1458a1a41901f1e1b31"
|
|
||||||
integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==
|
|
||||||
|
|
||||||
"d3-timer@1 - 3":
|
|
||||||
version "3.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0"
|
|
||||||
integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==
|
|
||||||
|
|
||||||
"d3-transition@2 - 3":
|
|
||||||
version "3.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-3.0.1.tgz#6869fdde1448868077fdd5989200cb61b2a1645f"
|
|
||||||
integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==
|
|
||||||
dependencies:
|
|
||||||
d3-color "1 - 3"
|
|
||||||
d3-dispatch "1 - 3"
|
|
||||||
d3-ease "1 - 3"
|
|
||||||
d3-interpolate "1 - 3"
|
|
||||||
d3-timer "1 - 3"
|
|
||||||
|
|
||||||
d3-zoom@^3.0.0:
|
|
||||||
version "3.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-3.0.0.tgz#d13f4165c73217ffeaa54295cd6969b3e7aee8f3"
|
|
||||||
integrity sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==
|
|
||||||
dependencies:
|
|
||||||
d3-dispatch "1 - 3"
|
|
||||||
d3-drag "2 - 3"
|
|
||||||
d3-interpolate "1 - 3"
|
|
||||||
d3-selection "2 - 3"
|
|
||||||
d3-transition "2 - 3"
|
|
||||||
|
|
||||||
damerau-levenshtein@^1.0.7:
|
damerau-levenshtein@^1.0.7:
|
||||||
version "1.0.8"
|
version "1.0.8"
|
||||||
resolved "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz"
|
resolved "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz"
|
||||||
@@ -9299,6 +8985,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6
|
|||||||
resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz"
|
resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz"
|
||||||
integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==
|
integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==
|
||||||
|
|
||||||
|
graphemer@^1.4.0:
|
||||||
|
version "1.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6"
|
||||||
|
integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
|
||||||
|
|
||||||
graphql-executor@0.0.18:
|
graphql-executor@0.0.18:
|
||||||
version "0.0.18"
|
version "0.0.18"
|
||||||
resolved "https://registry.npmjs.org/graphql-executor/-/graphql-executor-0.0.18.tgz"
|
resolved "https://registry.npmjs.org/graphql-executor/-/graphql-executor-0.0.18.tgz"
|
||||||
@@ -10236,6 +9927,11 @@ isexe@^3.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-3.1.1.tgz#4a407e2bd78ddfb14bea0c27c6f7072dde775f0d"
|
resolved "https://registry.yarnpkg.com/isexe/-/isexe-3.1.1.tgz#4a407e2bd78ddfb14bea0c27c6f7072dde775f0d"
|
||||||
integrity sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==
|
integrity sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==
|
||||||
|
|
||||||
|
iso-datestring-validator@^2.2.2:
|
||||||
|
version "2.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/iso-datestring-validator/-/iso-datestring-validator-2.2.2.tgz#2daa80d2900b7a954f9f731d42f96ee0c19a6895"
|
||||||
|
integrity sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==
|
||||||
|
|
||||||
isobject@^3.0.1:
|
isobject@^3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz"
|
resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz"
|
||||||
@@ -11952,6 +11648,11 @@ multicast-dns@^6.0.1:
|
|||||||
dns-packet "^1.3.1"
|
dns-packet "^1.3.1"
|
||||||
thunky "^1.0.2"
|
thunky "^1.0.2"
|
||||||
|
|
||||||
|
multiformats@^9.4.2, multiformats@^9.9.0:
|
||||||
|
version "9.9.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.9.0.tgz#c68354e7d21037a8f1f8833c8ccd68618e8f1d37"
|
||||||
|
integrity sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==
|
||||||
|
|
||||||
multimatch@^5.0.0:
|
multimatch@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz"
|
resolved "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz"
|
||||||
@@ -14169,18 +13870,6 @@ react@^18.2.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
loose-envify "^1.1.0"
|
loose-envify "^1.1.0"
|
||||||
|
|
||||||
reactflow@^11.11.2:
|
|
||||||
version "11.11.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/reactflow/-/reactflow-11.11.2.tgz#4968866a9372e6004ad1e424a2141996f0ba769a"
|
|
||||||
integrity sha512-o1fT3stSdhzW+SedCGNSmEvZvULZygZIMLyW67NcWNZrgwx1wuJfzLg5fuQ0Nzf389wItumZX/zP3zdaPX7lEw==
|
|
||||||
dependencies:
|
|
||||||
"@reactflow/background" "11.3.12"
|
|
||||||
"@reactflow/controls" "11.2.12"
|
|
||||||
"@reactflow/core" "11.11.2"
|
|
||||||
"@reactflow/minimap" "11.7.12"
|
|
||||||
"@reactflow/node-resizer" "2.2.12"
|
|
||||||
"@reactflow/node-toolbar" "1.3.12"
|
|
||||||
|
|
||||||
read-cmd-shim@^2.0.0:
|
read-cmd-shim@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-2.0.0.tgz"
|
resolved "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-2.0.0.tgz"
|
||||||
@@ -15946,6 +15635,11 @@ tinyspy@^2.2.0:
|
|||||||
resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-2.2.0.tgz#9dc04b072746520b432f77ea2c2d17933de5d6ce"
|
resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-2.2.0.tgz#9dc04b072746520b432f77ea2c2d17933de5d6ce"
|
||||||
integrity sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==
|
integrity sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==
|
||||||
|
|
||||||
|
tlds@^1.234.0:
|
||||||
|
version "1.252.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/tlds/-/tlds-1.252.0.tgz#71d9617f4ef4cc7347843bee72428e71b8b0f419"
|
||||||
|
integrity sha512-GA16+8HXvqtfEnw/DTcwB0UU354QE1n3+wh08oFjr6Znl7ZLAeUgYzCcK+/CCrOyE0vnHR8/pu3XXG3vDijXpQ==
|
||||||
|
|
||||||
tmp@^0.0.33:
|
tmp@^0.0.33:
|
||||||
version "0.0.33"
|
version "0.0.33"
|
||||||
resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz"
|
resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz"
|
||||||
@@ -16195,6 +15889,13 @@ uid-number@0.0.6:
|
|||||||
resolved "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz"
|
resolved "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz"
|
||||||
integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=
|
integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=
|
||||||
|
|
||||||
|
uint8arrays@3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.0.0.tgz#260869efb8422418b6f04e3fac73a3908175c63b"
|
||||||
|
integrity sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==
|
||||||
|
dependencies:
|
||||||
|
multiformats "^9.4.2"
|
||||||
|
|
||||||
umask@^1.1.0:
|
umask@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.npmjs.org/umask/-/umask-1.1.0.tgz"
|
resolved "https://registry.npmjs.org/umask/-/umask-1.1.0.tgz"
|
||||||
@@ -16349,11 +16050,6 @@ url-parse-lax@^3.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
prepend-http "^2.0.0"
|
prepend-http "^2.0.0"
|
||||||
|
|
||||||
use-sync-external-store@1.2.0:
|
|
||||||
version "1.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
|
|
||||||
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
|
|
||||||
|
|
||||||
util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
|
util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
|
resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
|
||||||
@@ -17326,9 +17022,7 @@ zen-observable@0.8.15:
|
|||||||
resolved "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz"
|
resolved "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz"
|
||||||
integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==
|
integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==
|
||||||
|
|
||||||
zustand@^4.4.1:
|
zod@^3.21.4:
|
||||||
version "4.5.2"
|
version "3.23.8"
|
||||||
resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.5.2.tgz#fddbe7cac1e71d45413b3682cdb47b48034c3848"
|
resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d"
|
||||||
integrity sha512-2cN1tPkDVkwCy5ickKrI7vijSjPksFRfqS6237NzT0vqSsztTNnQdHw9mmN7uBdk3gceVXU0a+21jFzFzAc9+g==
|
integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==
|
||||||
dependencies:
|
|
||||||
use-sync-external-store "1.2.0"
|
|
||||||
|
Reference in New Issue
Block a user