Merge branch 'main' into issue-553

This commit is contained in:
Ali BARIN
2022-10-12 18:02:53 +02:00
committed by GitHub
85 changed files with 1239 additions and 2369 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@automatisch/backend",
"version": "0.1.4",
"version": "0.1.5",
"license": "AGPL-3.0",
"description": "The open source Zapier alternative. Build workflow automation without spending time and money.",
"scripts": {
@@ -22,7 +22,7 @@
"prebuild": "rm -rf ./dist"
},
"dependencies": {
"@automatisch/web": "^0.1.4",
"@automatisch/web": "^0.1.5",
"@bull-board/express": "^3.10.1",
"@gitbeaker/node": "^35.6.0",
"@graphql-tools/graphql-file-loader": "^7.3.4",
@@ -100,7 +100,7 @@
"url": "https://github.com/automatisch/automatisch/issues"
},
"devDependencies": {
"@automatisch/types": "^0.1.4",
"@automatisch/types": "^0.1.5",
"@types/bcrypt": "^5.0.0",
"@types/bull": "^3.15.8",
"@types/cors": "^2.8.12",

View File

@@ -1,4 +0,0 @@
<svg fill="#5865f2" aria-label="Discord" role="img" version="1.1" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
<rect width="512" height="512" rx="15%" fill="#fff"/>
<path d="m386 137c-24-11-49.5-19-76.3-23.7c-.5 0-1 0-1.2.6c-3.3 5.9-7 13.5-9.5 19.5c-29-4.3-57.5-4.3-85.7 0c-2.6-6.2-6.3-13.7-10-19.5c-.3-.4-.7-.7-1.2-.6c-23 4.6-52.4 13-76 23.7c-.2 0-.4.2-.5.4c-49 73-62 143-55 213c0 .3.2.7.5 1c32 23.6 63 38 93.6 47.3c.5 0 1 0 1.3-.4c7.2-9.8 13.6-20.2 19.2-31.2c.3-.6 0-1.4-.7-1.6c-10-4-20-8.6-29.3-14c-.7-.4-.8-1.5 0-2c2-1.5 4-3 5.8-4.5c.3-.3.8-.3 1.2-.2c61.4 28 128 28 188 0c.4-.2.9-.1 1.2.1c1.9 1.6 3.8 3.1 5.8 4.6c.7.5.6 1.6 0 2c-9.3 5.5-19 10-29.3 14c-.7.3-1 1-.6 1.7c5.6 11 12.1 21.3 19 31c.3.4.8.6 1.3.4c30.6-9.5 61.7-23.8 93.8-47.3c.3-.2.5-.5.5-1c7.8-80.9-13.1-151-55.4-213c0-.2-.3-.4-.5-.4Zm-192 171c-19 0-34-17-34-38c0-21 15-38 34-38c19 0 34 17 34 38c0 21-15 38-34 38zm125 0c-19 0-34-17-34-38c0-21 15-38 34-38c19 0 34 17 34 38c0 21-15 38-34 38z" fill="#5865f2"/>
</svg>

Before

Width:  |  Height:  |  Size: 993 B

View File

@@ -1,99 +0,0 @@
import type {
IAuthentication,
IApp,
IField,
IJSONObject,
} from '@automatisch/types';
import { URLSearchParams } from 'url';
import axios, { AxiosInstance } from 'axios';
export default class Authentication implements IAuthentication {
appData: IApp;
connectionData: IJSONObject;
client: AxiosInstance = axios.create({
baseURL: 'https://discord.com/api/',
});
scope: string[] = ['identify', 'email'];
constructor(appData: IApp, connectionData: IJSONObject) {
this.appData = appData;
this.connectionData = connectionData;
}
get oauthRedirectUrl() {
return this.appData.fields.find(
(field: IField) => field.key == 'oAuthRedirectUrl'
).value;
}
async createAuthData() {
const searchParams = new URLSearchParams({
client_id: this.connectionData.consumerKey as string,
redirect_uri: this.oauthRedirectUrl,
response_type: 'code',
scope: this.scope.join(' '),
});
const url = `https://discord.com/api/oauth2/authorize?${searchParams.toString()}`;
return { url };
}
async verifyCredentials() {
const params = new URLSearchParams({
client_id: this.connectionData.consumerKey as string,
redirect_uri: this.oauthRedirectUrl,
response_type: 'code',
scope: this.scope.join(' '),
client_secret: this.connectionData.consumerSecret as string,
code: this.connectionData.oauthVerifier as string,
grant_type: 'authorization_code',
});
const { data: verifiedCredentials } = await this.client.post(
'/oauth2/token',
params.toString()
);
const {
access_token: accessToken,
refresh_token: refreshToken,
expires_in: expiresIn,
scope: scope,
token_type: tokenType,
} = verifiedCredentials;
const { data: user } = await this.client.get('/users/@me', {
headers: {
Authorization: `${tokenType} ${accessToken}`,
},
});
return {
consumerKey: this.connectionData.consumerKey,
consumerSecret: this.connectionData.consumerSecret,
accessToken,
refreshToken,
expiresIn,
scope,
tokenType,
userId: user.id,
screenName: user.username,
email: user.email,
};
}
async isStillVerified() {
try {
await this.client.get('/users/@me', {
headers: {
Authorization: `${this.connectionData.tokenType} ${this.connectionData.accessToken}`,
},
});
return true;
} catch {
return false;
}
}
}

View File

@@ -1,15 +0,0 @@
import Authentication from './authentication';
import {
IService,
IAuthentication,
IApp,
IJSONObject,
} from '@automatisch/types';
export default class Discord implements IService {
authenticationClient: IAuthentication;
constructor(appData: IApp, connectionData: IJSONObject) {
this.authenticationClient = new Authentication(appData, connectionData);
}
}

View File

@@ -1,219 +0,0 @@
{
"name": "Discord",
"key": "discord",
"iconUrl": "{BASE_URL}/apps/discord/assets/favicon.svg",
"docUrl": "https://automatisch.io/docs/discord",
"primaryColor": "5865f2",
"supportsConnections": true,
"fields": [
{
"key": "oAuthRedirectUrl",
"label": "OAuth Redirect URL",
"type": "string",
"required": true,
"readOnly": true,
"value": "{WEB_APP_URL}/app/discord/connections/add",
"placeholder": null,
"description": "When asked to input an OAuth callback or redirect URL in Discord OAuth, enter the URL above.",
"docUrl": "https://automatisch.io/docs/discord#oauth-redirect-url",
"clickToCopy": true
},
{
"key": "consumerKey",
"label": "Consumer Key",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/discord#consumer-key",
"clickToCopy": false
},
{
"key": "consumerSecret",
"label": "Consumer Secret",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/discord#consumer-secret",
"clickToCopy": false
}
],
"authenticationSteps": [
{
"step": 1,
"type": "mutation",
"name": "createConnection",
"arguments": [
{
"name": "key",
"value": "{key}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "consumerKey",
"value": "{fields.consumerKey}"
},
{
"name": "consumerSecret",
"value": "{fields.consumerSecret}"
}
]
}
]
},
{
"step": 2,
"type": "mutation",
"name": "createAuthData",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
}
]
},
{
"step": 3,
"type": "openWithPopup",
"name": "openAuthPopup",
"arguments": [
{
"name": "url",
"value": "{createAuthData.url}"
}
]
},
{
"step": 4,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "oauthVerifier",
"value": "{openAuthPopup.code}"
}
]
}
]
},
{
"step": 5,
"type": "mutation",
"name": "verifyConnection",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
}
]
}
],
"reconnectionSteps": [
{
"step": 1,
"type": "mutation",
"name": "resetConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
},
{
"step": 2,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "consumerKey",
"value": "{fields.consumerKey}"
},
{
"name": "consumerSecret",
"value": "{fields.consumerSecret}"
}
]
}
]
},
{
"step": 3,
"type": "mutation",
"name": "createAuthData",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
},
{
"step": 4,
"type": "openWithPopup",
"name": "openAuthPopup",
"arguments": [
{
"name": "url",
"value": "{createAuthData.url}"
}
]
},
{
"step": 5,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "oauthVerifier",
"value": "{openAuthPopup.code}"
}
]
}
]
},
{
"step": 6,
"type": "mutation",
"name": "verifyConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
}
]
}

View File

@@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="256px" height="351px" viewBox="0 0 256 351" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
<defs>
<path d="M1.25273437,280.731641 L2.85834533,277.600858 L102.211177,89.0833546 L58.0613266,5.6082033 C54.3920011,-1.28304578 45.0741245,0.473674398 43.8699203,8.18789086 L1.25273437,280.731641 Z" id="path-1"></path>
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-2">
<feGaussianBlur stdDeviation="17.5" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
<feOffset dx="0" dy="0" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
<feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" type="matrix" in="shadowInnerInner1"></feColorMatrix>
</filter>
<path d="M134.417103,148.974235 L166.455722,116.161738 L134.417104,55.1546874 C131.374828,49.3635911 123.983911,48.7568362 120.973828,54.5646483 L103.26875,88.6738296 L102.739423,90.4175473 L134.417103,148.974235 Z" id="path-3"></path>
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-4">
<feGaussianBlur stdDeviation="3.5" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
<feOffset dx="1" dy="-9" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
<feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.09 0" type="matrix" in="shadowInnerInner1"></feColorMatrix>
</filter>
</defs>
<g>
<path d="M0,282.99762 L2.12250746,280.0256 L102.527363,89.5119284 L102.739423,87.4951323 L58.478806,4.35817711 C54.7706269,-2.60604179 44.3313035,-0.845245771 43.1143483,6.95065473 L0,282.99762 Z" fill="#FFC24A"></path>
<g>
<use fill="#FFA712" fill-rule="evenodd" xlink:href="#path-1"></use>
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
</g>
<path d="M135.004975,150.380704 L167.960199,116.629461 L134.995423,53.6993114 C131.866109,47.7425353 123.128817,47.7253411 120.032618,53.6993112 L102.421015,87.2880848 L102.421015,90.1487443 L135.004975,150.380704 Z" fill="#F4BD62"></path>
<g>
<use fill="#FFA50E" fill-rule="evenodd" xlink:href="#path-3"></use>
<use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-3"></use>
</g>
<polygon fill="#F6820C" points="0 282.99762 0.962097168 282.030396 4.45771144 280.60956 132.935323 152.60956 134.563025 148.178595 102.513123 87.1048584"></polygon>
<path d="M139.120971,347.551268 L255.395916,282.703666 L222.191698,78.2093373 C221.153051,71.8112478 213.303658,69.2818149 208.724314,73.8694368 L0.000254726368,282.997875 L115.608454,347.545536 C122.914643,351.624979 131.812872,351.62689 139.120971,347.551268" fill="#FDE068"></path>
<path d="M254.354084,282.159837 L221.401937,79.2179369 C220.371175,72.8684188 213.843792,70.2409553 209.299213,74.79375 L1.28945312,282.600785 L115.627825,346.509458 C122.878548,350.557931 131.709226,350.559827 138.961846,346.515146 L254.354084,282.159837 Z" fill="#FCCA3F"></path>
<path d="M139.120907,345.64082 C131.812808,349.716442 122.914579,349.714531 115.60839,345.635089 L0.93134768,282.014551 L0.000191044776,282.997875 L115.60839,347.545536 C122.914579,351.624979 131.812808,351.62689 139.120907,347.551268 L255.395853,282.703666 L255.111196,280.951785 L139.120907,345.64082 Z" fill="#EEAB37"></path>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -1,89 +0,0 @@
import type {
IAuthentication,
IApp,
IField,
IJSONObject,
} from '@automatisch/types';
import { google as GoogleApi } from 'googleapis';
import { OAuth2Client } from 'google-auth-library';
export default class Authentication implements IAuthentication {
appData: IApp;
connectionData: IJSONObject;
client: OAuth2Client;
scopes: string[] = [
'https://www.googleapis.com/auth/datastore',
'https://www.googleapis.com/auth/firebase',
'https://www.googleapis.com/auth/user.emails.read',
'profile',
];
constructor(appData: IApp, connectionData: IJSONObject) {
this.appData = appData;
this.connectionData = connectionData;
this.client = new GoogleApi.auth.OAuth2(
connectionData.consumerKey as string,
connectionData.consumerSecret as string,
this.oauthRedirectUrl
);
GoogleApi.options({ auth: this.client });
}
get oauthRedirectUrl() {
return this.appData.fields.find(
(field: IField) => field.key == 'oAuthRedirectUrl'
).value;
}
async createAuthData() {
const url = this.client.generateAuthUrl({
access_type: 'offline',
scope: this.scopes,
});
return { url };
}
async verifyCredentials() {
const { tokens } = await this.client.getToken(
this.connectionData.oauthVerifier as string
);
this.client.setCredentials(tokens);
const people = GoogleApi.people('v1');
const { data } = await people.people.get({
resourceName: 'people/me',
personFields: 'emailAddresses',
});
const { emailAddresses, resourceName: userId } = data;
const primaryEmailAddress = emailAddresses.find(
(emailAddress) => emailAddress.metadata.primary
);
return {
consumerKey: this.connectionData.consumerKey,
consumerSecret: this.connectionData.consumerSecret,
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
tokenType: tokens.token_type,
expiryDate: tokens.expiry_date,
scope: tokens.scope,
screenName: primaryEmailAddress.value,
userId,
};
}
async isStillVerified() {
try {
await this.client.getTokenInfo(this.connectionData.accessToken as string);
return true;
} catch {
return false;
}
}
}

View File

@@ -1,15 +0,0 @@
import Authentication from './authentication';
import {
IService,
IAuthentication,
IApp,
IJSONObject,
} from '@automatisch/types';
export default class Firebase implements IService {
authenticationClient: IAuthentication;
constructor(appData: IApp, connectionData: IJSONObject) {
this.authenticationClient = new Authentication(appData, connectionData);
}
}

View File

@@ -1,219 +0,0 @@
{
"name": "Firebase",
"key": "firebase",
"iconUrl": "{BASE_URL}/apps/firebase/assets/favicon.svg",
"docUrl": "https://automatisch.io/docs/firebase",
"primaryColor": "ffca28",
"supportsConnections": true,
"fields": [
{
"key": "oAuthRedirectUrl",
"label": "OAuth Redirect URL",
"type": "string",
"required": true,
"readOnly": true,
"value": "{WEB_APP_URL}/app/firebase/connections/add",
"placeholder": null,
"description": "When asked to input an OAuth callback or redirect URL in Firebase OAuth, enter the URL above.",
"docUrl": "https://automatisch.io/docs/firebase#oauth-redirect-url",
"clickToCopy": true
},
{
"key": "consumerKey",
"label": "Consumer Key",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/firebase#consumer-key",
"clickToCopy": false
},
{
"key": "consumerSecret",
"label": "Consumer Secret",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/firebase#consumer-secret",
"clickToCopy": false
}
],
"authenticationSteps": [
{
"step": 1,
"type": "mutation",
"name": "createConnection",
"arguments": [
{
"name": "key",
"value": "{key}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "consumerKey",
"value": "{fields.consumerKey}"
},
{
"name": "consumerSecret",
"value": "{fields.consumerSecret}"
}
]
}
]
},
{
"step": 2,
"type": "mutation",
"name": "createAuthData",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
}
]
},
{
"step": 3,
"type": "openWithPopup",
"name": "openAuthPopup",
"arguments": [
{
"name": "url",
"value": "{createAuthData.url}"
}
]
},
{
"step": 4,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "oauthVerifier",
"value": "{openAuthPopup.code}"
}
]
}
]
},
{
"step": 5,
"type": "mutation",
"name": "verifyConnection",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
}
]
}
],
"reconnectionSteps": [
{
"step": 1,
"type": "mutation",
"name": "resetConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
},
{
"step": 2,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "consumerKey",
"value": "{fields.consumerKey}"
},
{
"name": "consumerSecret",
"value": "{fields.consumerSecret}"
}
]
}
]
},
{
"step": 3,
"type": "mutation",
"name": "createAuthData",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
},
{
"step": 4,
"type": "openWithPopup",
"name": "openAuthPopup",
"arguments": [
{
"name": "url",
"value": "{createAuthData.url}"
}
]
},
{
"step": 5,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "oauthVerifier",
"value": "{openAuthPopup.code}"
}
]
}
]
},
{
"step": 6,
"type": "mutation",
"name": "verifyConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
}
]
}

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<svg width="256px" height="236px" viewBox="0 0 256 236" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
<g>
<path d="M128.07485,236.074667 L128.07485,236.074667 L175.17885,91.1043048 L80.9708495,91.1043048 L128.07485,236.074667 L128.07485,236.074667 Z" fill="#E24329"></path>
<path d="M128.07485,236.074423 L80.9708495,91.104061 L14.9557638,91.104061 L128.07485,236.074423 L128.07485,236.074423 Z" fill="#FC6D26"></path>
<path d="M14.9558857,91.1044267 L14.9558857,91.1044267 L0.641828571,135.159589 C-0.663771429,139.17757 0.766171429,143.57955 4.18438095,146.06275 L128.074971,236.074789 L14.9558857,91.1044267 L14.9558857,91.1044267 Z" fill="#FCA326"></path>
<path d="M14.9558857,91.1045486 L80.9709714,91.1045486 L52.6000762,3.79026286 C51.1408762,-0.703146667 44.7847619,-0.701927619 43.3255619,3.79026286 L14.9558857,91.1045486 L14.9558857,91.1045486 Z" fill="#E24329"></path>
<path d="M128.07485,236.074423 L175.17885,91.104061 L241.193935,91.104061 L128.07485,236.074423 L128.07485,236.074423 Z" fill="#FC6D26"></path>
<path d="M241.193935,91.1044267 L241.193935,91.1044267 L255.507992,135.159589 C256.813592,139.17757 255.38365,143.57955 251.96544,146.06275 L128.07485,236.074789 L241.193935,91.1044267 L241.193935,91.1044267 Z" fill="#FCA326"></path>
<path d="M241.193935,91.1045486 L175.17885,91.1045486 L203.549745,3.79026286 C205.008945,-0.703146667 211.365059,-0.701927619 212.824259,3.79026286 L241.193935,91.1045486 L241.193935,91.1045486 Z" fill="#E24329"></path>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -1,101 +0,0 @@
import { URLSearchParams } from 'url';
import axios from 'axios';
import crypto from 'crypto';
import { Gitlab } from '@gitbeaker/node';
import type {
IAuthentication,
IApp,
IField,
IJSONObject,
} from '@automatisch/types';
export default class Authentication implements IAuthentication {
appData: IApp;
connectionData: IJSONObject;
client: any;
scopes = [
'api',
'profile',
'email',
];
constructor(appData: IApp, connectionData: IJSONObject) {
this.connectionData = connectionData;
this.appData = appData;
if (connectionData?.accessToken) {
this.client = new Gitlab({
host: this.host,
oauthToken: connectionData?.accessToken as string,
});
}
}
get host() {
return `https://${this.connectionData.host}`;
}
get oauthRedirectUrl() {
return this.appData.fields.find(
(field: IField) => field.key == 'oAuthRedirectUrl'
).value;
}
async createAuthData() {
const state = crypto.randomUUID();
const searchParams = new URLSearchParams({
client_id: this.connectionData.applicationId as string,
redirect_uri: this.oauthRedirectUrl,
response_type: 'code',
scope: this.scopes.join(' '),
state,
});
const url = `${this.host}/oauth/authorize?${searchParams.toString()}`;
return { url };
}
async verifyCredentials() {
const params = new URLSearchParams({
client_id: this.connectionData.applicationId as string,
grant_type: 'authorization_code',
redirect_uri: this.oauthRedirectUrl,
code: this.connectionData.oauthVerifier as string,
client_secret: this.connectionData.secret as string,
});
const { data } = await axios.post(`${this.host}/oauth/token`, params.toString());
const accessToken = data.access_token;
const client = new Gitlab({
host: this.host,
oauthToken: accessToken,
});
const user = await client.Users.current();
return {
host: this.connectionData.host as string,
applicationId: this.connectionData.applicationId as string,
secret: this.connectionData.secret,
accessToken: data.access_token,
refreshToken: data.refresh_token,
expiresIn: data.expires_in,
tokenType: data.token_type,
userId: user.id,
screenName: user.name,
username: user.username,
};
}
async isStillVerified() {
try {
await this.client.Users.current();
return true;
} catch (err) {
return false;
}
}
}

View File

@@ -1,15 +0,0 @@
import Authentication from './authentication';
import {
IService,
IAuthentication,
IApp,
IJSONObject,
} from '@automatisch/types';
export default class Gitlab implements IService {
authenticationClient: IAuthentication;
constructor(appData: IApp, connectionData: IJSONObject) {
this.authenticationClient = new Authentication(appData, connectionData);
}
}

View File

@@ -1,239 +0,0 @@
{
"name": "GitLab",
"key": "gitlab",
"iconUrl": "{BASE_URL}/apps/gitlab/assets/favicon.svg",
"docUrl": "https://automatisch.io/docs/gitlab",
"primaryColor": "2DAAE1",
"supportsConnections": true,
"fields": [
{
"key": "oAuthRedirectUrl",
"label": "OAuth Redirect URL",
"type": "string",
"required": true,
"readOnly": true,
"value": "{WEB_APP_URL}/app/gitlab/connections/add",
"placeholder": null,
"description": "When asked to input an OAuth callback or redirect URL in GitLab OAuth, enter the URL above.",
"docUrl": "https://automatisch.io/docs/gitlab#oauth-redirect-url",
"clickToCopy": true
},
{
"key": "host",
"label": "GitLab Host",
"type": "string",
"required": true,
"readOnly": false,
"value": "gitlab.com",
"placeholder": null,
"description": "Only required if you host your own instance of GitLab. If you access GitLab by going to https://www.example.com, enter www.example.com here.",
"docUrl": "https://automatisch.io/docs/gitlab#host",
"clickToCopy": false
},
{
"key": "applicationId",
"label": "Application ID",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/gitlab#application-id",
"clickToCopy": false
},
{
"key": "secret",
"label": "Secret",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/gitlab#secret",
"clickToCopy": false
}
],
"authenticationSteps": [
{
"step": 1,
"type": "mutation",
"name": "createConnection",
"arguments": [
{
"name": "key",
"value": "{key}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "host",
"value": "{fields.host}"
},
{
"name": "applicationId",
"value": "{fields.applicationId}"
},
{
"name": "secret",
"value": "{fields.secret}"
}
]
}
]
},
{
"step": 2,
"type": "mutation",
"name": "createAuthData",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
}
]
},
{
"step": 3,
"type": "openWithPopup",
"name": "openAuthPopup",
"arguments": [
{
"name": "url",
"value": "{createAuthData.url}"
}
]
},
{
"step": 4,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "oauthVerifier",
"value": "{openAuthPopup.code}"
}
]
}
]
},
{
"step": 5,
"type": "mutation",
"name": "verifyConnection",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
}
]
}
],
"reconnectionSteps": [
{
"step": 1,
"type": "mutation",
"name": "resetConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
},
{
"step": 2,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "host",
"value": "{fields.host}"
},
{
"name": "applicationId",
"value": "{fields.applicationId}"
},
{
"name": "secret",
"value": "{fields.secret}"
}
]
}
]
},
{
"step": 3,
"type": "mutation",
"name": "createAuthData",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
},
{
"step": 4,
"type": "openWithPopup",
"name": "openAuthPopup",
"arguments": [
{
"name": "url",
"value": "{createAuthData.url}"
}
]
},
{
"step": 5,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "oauthVerifier",
"value": "{openAuthPopup.code}"
}
]
}
]
},
{
"step": 6,
"type": "mutation",
"name": "verifyConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
}
]
}

View File

@@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg"
aria-label="Mail" role="img"
viewBox="0 0 512 512"><rect
width="512" height="512"
rx="15%"
fill="#328cff"/><path d="m250 186c-46 0-69 35-69 74 0 44 29 72 68 72 43 0 73-32 73-75 0-44-34-71-72-71zm-1-37c30 0 57 13 77 33 0-22 35-22 35 1v150c-1 10 10 16 16 9 25-25 54-128-14-187-64-56-149-47-195-15-48 33-79 107-49 175 33 76 126 99 182 76 28-12 41 26 12 39-45 19-168 17-225-82-38-68-36-185 67-248 78-46 182-33 244 32 66 69 62 197-2 246-28 23-71 1-71-32v-11c-20 20-47 32-77 32-57 0-108-51-108-108 0-58 51-110 108-110" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 573 B

View File

@@ -1,44 +0,0 @@
import nodemailer, { Transporter, TransportOptions } from 'nodemailer';
import type {
IAuthentication,
IApp,
IJSONObject,
} from '@automatisch/types';
export default class Authentication implements IAuthentication {
appData: IApp;
connectionData: IJSONObject;
client: Transporter;
constructor(appData: IApp, connectionData: IJSONObject) {
this.client = nodemailer.createTransport({
host: connectionData.host,
port: connectionData.port,
secure: connectionData.useTls,
auth: {
user: connectionData.username,
pass: connectionData.password,
},
} as TransportOptions);
this.connectionData = connectionData;
this.appData = appData;
}
async verifyCredentials() {
await this.client.verify();
return {
screenName: this.connectionData.username,
};
}
async isStillVerified() {
try {
await this.client.verify();
return true;
} catch (error) {
return false;
}
}
}

View File

@@ -1,15 +0,0 @@
import Authentication from './authentication';
import {
IService,
IAuthentication,
IApp,
IJSONObject,
} from '@automatisch/types';
export default class SMTP implements IService {
authenticationClient: IAuthentication;
constructor(appData: IApp, connectionData: IJSONObject) {
this.authenticationClient = new Authentication(appData, connectionData);
}
}

View File

@@ -1,201 +0,0 @@
{
"name": "SMTP",
"key": "smtp",
"iconUrl": "{BASE_URL}/apps/smtp/assets/favicon.svg",
"docUrl": "https://automatisch.io/docs/smtp",
"primaryColor": "2DAAE1",
"supportsConnections": true,
"fields": [
{
"key": "host",
"label": "Host",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": "The host information Automatisch will connect to.",
"docUrl": "https://automatisch.io/docs/smtp#host",
"clickToCopy": false
},
{
"key": "username",
"label": "Email/Username",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": "Your SMTP login credentials.",
"docUrl": "https://automatisch.io/docs/smtp#username",
"clickToCopy": false
},
{
"key": "password",
"label": "Password",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/smtp#password",
"clickToCopy": false
},
{
"key": "useTls",
"label": "Use TLS?",
"type": "boolean",
"required": false,
"readOnly": false,
"value": false,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/smtp#use-tls",
"clickToCopy": false
},
{
"key": "port",
"label": "Port",
"type": "integer",
"required": false,
"readOnly": false,
"value": 25,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/smtp#port",
"clickToCopy": false
},
{
"key": "fromEmail",
"label": "From Email",
"type": "string",
"required": false,
"readOnly": false,
"value": null,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/smtp#from-email",
"clickToCopy": false
}
],
"authenticationSteps": [
{
"step": 1,
"type": "mutation",
"name": "createConnection",
"arguments": [
{
"name": "key",
"value": "{key}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "host",
"value": "{fields.host}"
},
{
"name": "username",
"value": "{fields.username}"
},
{
"name": "password",
"value": "{fields.password}"
},
{
"name": "useTLS",
"value": "{fields.useTls}"
},
{
"name": "port",
"value": "{fields.port}"
},
{
"name": "fromEmail",
"value": "{fields.fromEmail}"
}
]
}
]
},
{
"step": 2,
"type": "mutation",
"name": "verifyConnection",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
}
]
}
],
"reconnectionSteps": [
{
"step": 1,
"type": "mutation",
"name": "resetConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
},
{
"step": 2,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "host",
"value": "{fields.host}"
},
{
"name": "username",
"value": "{fields.username}"
},
{
"name": "password",
"value": "{fields.password}"
},
{
"name": "useTLS",
"value": "{fields.useTls}"
},
{
"name": "port",
"value": "{fields.port}"
},
{
"name": "fromEmail",
"value": "{fields.fromEmail}"
}
]
}
]
},
{
"step": 3,
"type": "mutation",
"name": "verifyConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
}
]
}

View File

@@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
aria-label="Twilio" role="img"
viewBox="0 0 512 512"><rect
width="512" height="512"
rx="15%"
fill="#fff"/><g fill="#f22f46"><circle cx="256" cy="256" r="256"/><circle cx="256" cy="256" fill="#fff" r="188"/><circle cx="193" cy="193" r="53" id="c"/><use xlink:href="#c" x="126"/><use xlink:href="#c" y="126"/><use xlink:href="#c" x="126" y="126"/></g></svg>

Before

Width:  |  Height:  |  Size: 438 B

View File

@@ -1,44 +0,0 @@
import type {
IAuthentication,
IApp,
IJSONObject,
} from '@automatisch/types';
import TwilioApi from 'twilio';
export default class Authentication implements IAuthentication {
appData: IApp;
connectionData: IJSONObject;
client: TwilioApi.Twilio;
constructor(appData: IApp, connectionData: IJSONObject) {
this.client = TwilioApi(
connectionData.accountSid as string,
connectionData.authToken as string
);
this.connectionData = connectionData;
this.appData = appData;
}
async verifyCredentials() {
await this.verify();
return {
screenName: this.connectionData.accountSid,
};
}
async verify() {
try {
await this.client.keys.list({ limit: 1 });
return true;
} catch (error) {
// Test credentials throw HTTP 403 and thus, we need to have an exception.
return error?.status === 403;
}
}
async isStillVerified() {
return this.verify();
}
}

View File

@@ -1,15 +0,0 @@
import Authentication from './authentication';
import {
IService,
IAuthentication,
IApp,
IJSONObject,
} from '@automatisch/types';
export default class Twilio implements IService {
authenticationClient: IAuthentication;
constructor(appData: IApp, connectionData: IJSONObject) {
this.authenticationClient = new Authentication(appData, connectionData);
}
}

View File

@@ -1,121 +0,0 @@
{
"name": "Twilio",
"key": "twilio",
"iconUrl": "{BASE_URL}/apps/twilio/assets/favicon.svg",
"docUrl": "https://automatisch.io/docs/twilio",
"primaryColor": "f22f46",
"supportsConnections": true,
"fields": [
{
"key": "accountSid",
"label": "Account SID",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": "Log into your Twilio account and find \"API Credentials\" on this page https://www.twilio.com/user/account/settings",
"docUrl": "https://automatisch.io/docs/twilio#host",
"clickToCopy": false
},
{
"key": "authToken",
"label": "Auth Token",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": "Found directly below your Account SID.",
"docUrl": "https://automatisch.io/docs/twilio#username",
"clickToCopy": false
}
],
"authenticationSteps": [
{
"step": 1,
"type": "mutation",
"name": "createConnection",
"arguments": [
{
"name": "key",
"value": "{key}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "accountSid",
"value": "{fields.accountSid}"
},
{
"name": "authToken",
"value": "{fields.authToken}"
}
]
}
]
},
{
"step": 2,
"type": "mutation",
"name": "verifyConnection",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
}
]
}
],
"reconnectionSteps": [
{
"step": 1,
"type": "mutation",
"name": "resetConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
},
{
"step": 2,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "accountSid",
"value": "{fields.accountSid}"
},
{
"name": "authToken",
"value": "{fields.authToken}"
}
]
}
]
},
{
"step": 3,
"type": "mutation",
"name": "verifyConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
}
]
}

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" aria-label="Twitch" role="img" viewBox="0 0 512 512">
<rect width="512" height="512" rx="15%" fill="#fff"/>
<path d="m115 101-22 56v228h78v42h44l41-42h63l85-85v-199zm260 185-48 48h-78l-42 42v-42h-65v-204h233zm-48-100v85h-30v-85zm-78 0v85h-29v-85z" fill="#6441a4"/>
</svg>

Before

Width:  |  Height:  |  Size: 316 B

View File

@@ -1,105 +0,0 @@
import type {
IAuthentication,
IApp,
IField,
IJSONObject,
} from '@automatisch/types';
import TwitchApi, { TwitchJsOptions } from 'twitch-js';
import fetchUtil from 'twitch-js/lib/utils/fetch';
type TwitchTokenResponse = {
accessToken: string;
refreshToken: string;
expiresIn: string;
tokenType: string;
};
export default class Authentication implements IAuthentication {
appData: IApp;
connectionData: IJSONObject;
client: TwitchApi;
constructor(appData: IApp, connectionData: IJSONObject) {
this.connectionData = connectionData;
this.appData = appData;
if (this.clientOptions.token) {
this.client = new TwitchApi(this.clientOptions as TwitchJsOptions);
}
}
get clientOptions() {
return {
token: this.connectionData.accessToken,
clientId: this.connectionData.consumerKey,
log: { enabled: true },
};
}
get oauthRedirectUrl() {
return this.appData.fields.find(
(field: IField) => field.key == 'oAuthRedirectUrl'
).value;
}
async createAuthData() {
const { url } = await fetchUtil('https://id.twitch.tv/oauth2/authorize', {
search: {
client_id: this.connectionData.consumerKey,
redirect_uri: this.oauthRedirectUrl,
response_type: 'code',
scope: 'user:read:email',
},
});
return { url };
}
async verifyCredentials() {
const verifiedCredentials = (await fetchUtil(
'https://id.twitch.tv/oauth2/token',
{
method: 'post',
search: {
client_id: this.connectionData.consumerKey,
client_secret: this.connectionData.consumerSecret,
code: this.connectionData.oauthVerifier,
grant_type: 'authorization_code',
redirect_uri: this.oauthRedirectUrl,
},
}
)) as TwitchTokenResponse;
this.connectionData.accessToken = verifiedCredentials.accessToken;
const { api } = new TwitchApi(this.clientOptions as TwitchJsOptions);
const { data } = await api.get('users');
const [user] = data;
return {
consumerKey: this.connectionData.consumerKey,
consumerSecret: this.connectionData.consumerSecret,
accessToken: verifiedCredentials.accessToken,
refreshToken: verifiedCredentials.refreshToken,
expiresIn: verifiedCredentials.expiresIn,
tokenType: verifiedCredentials.tokenType,
userId: user.id,
screenName: user.displayName,
};
}
async isStillVerified() {
try {
await fetchUtil('https://id.twitch.tv/oauth2/userinfo', {
headers: {
Authorization: `Bearer ${this.connectionData.accessToken}`,
},
});
return true;
} catch (err) {
return false;
}
}
}

View File

@@ -1,15 +0,0 @@
import Authentication from './authentication';
import {
IService,
IAuthentication,
IApp,
IJSONObject,
} from '@automatisch/types';
export default class Twitch implements IService {
authenticationClient: IAuthentication;
constructor(appData: IApp, connectionData: IJSONObject) {
this.authenticationClient = new Authentication(appData, connectionData);
}
}

View File

@@ -1,219 +0,0 @@
{
"name": "Twitch",
"key": "twitch",
"iconUrl": "{BASE_URL}/apps/twitch/assets/favicon.svg",
"docUrl": "https://automatisch.io/docs/twitch",
"primaryColor": "2DAAE1",
"supportsConnections": true,
"fields": [
{
"key": "oAuthRedirectUrl",
"label": "OAuth Redirect URL",
"type": "string",
"required": true,
"readOnly": true,
"value": "{WEB_APP_URL}/app/twitch/connections/add",
"placeholder": null,
"description": "When asked to input an OAuth callback or redirect URL in Twitch OAuth, enter the URL above.",
"docUrl": "https://automatisch.io/docs/twitch#oauth-redirect-url",
"clickToCopy": true
},
{
"key": "consumerKey",
"label": "Consumer Key",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/twitch#consumer-key",
"clickToCopy": false
},
{
"key": "consumerSecret",
"label": "Consumer Secret",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/twitch#consumer-secret",
"clickToCopy": false
}
],
"authenticationSteps": [
{
"step": 1,
"type": "mutation",
"name": "createConnection",
"arguments": [
{
"name": "key",
"value": "{key}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "consumerKey",
"value": "{fields.consumerKey}"
},
{
"name": "consumerSecret",
"value": "{fields.consumerSecret}"
}
]
}
]
},
{
"step": 2,
"type": "mutation",
"name": "createAuthData",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
}
]
},
{
"step": 3,
"type": "openWithPopup",
"name": "openAuthPopup",
"arguments": [
{
"name": "url",
"value": "{createAuthData.url}"
}
]
},
{
"step": 4,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "oauthVerifier",
"value": "{openAuthPopup.code}"
}
]
}
]
},
{
"step": 5,
"type": "mutation",
"name": "verifyConnection",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
}
]
}
],
"reconnectionSteps": [
{
"step": 1,
"type": "mutation",
"name": "resetConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
},
{
"step": 2,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "consumerKey",
"value": "{fields.consumerKey}"
},
{
"name": "consumerSecret",
"value": "{fields.consumerSecret}"
}
]
}
]
},
{
"step": 3,
"type": "mutation",
"name": "createAuthData",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
},
{
"step": 4,
"type": "openWithPopup",
"name": "openAuthPopup",
"arguments": [
{
"name": "url",
"value": "{createAuthData.url}"
}
]
},
{
"step": 5,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "oauthVerifier",
"value": "{openAuthPopup.code}"
}
]
}
]
},
{
"step": 6,
"type": "mutation",
"name": "verifyConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
}
]
}

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -1,100 +0,0 @@
import type {
IAuthentication,
IApp,
IField,
IJSONObject,
} from '@automatisch/types';
import { URLSearchParams } from 'url';
import createHttpClient, { IHttpClient } from '../../helpers/http-client';
export default class Authentication implements IAuthentication {
appData: IApp;
connectionData: IJSONObject;
client: IHttpClient;
scope: string[] = [
'forms:read',
'forms:write',
'webhooks:read',
'webhooks:write',
'responses:read',
'accounts:read',
'workspaces:read',
];
constructor(appData: IApp, connectionData: IJSONObject) {
this.connectionData = connectionData;
this.appData = appData;
this.client = createHttpClient({ baseURL: 'https://api.typeform.com' });
}
get oauthRedirectUrl() {
return this.appData.fields.find(
(field: IField) => field.key == 'oAuthRedirectUrl'
).value;
}
async createAuthData() {
const searchParams = new URLSearchParams({
client_id: this.connectionData.consumerKey as string,
redirect_uri: this.oauthRedirectUrl,
scope: this.scope.join(' '),
});
const url = `https://api.typeform.com/oauth/authorize?${searchParams.toString()}`;
return { url };
}
async verifyCredentials() {
const params = new URLSearchParams({
grant_type: 'authorization_code',
code: this.connectionData.oauthVerifier as string,
client_id: this.connectionData.consumerKey as string,
client_secret: this.connectionData.consumerSecret as string,
redirect_uri: this.oauthRedirectUrl,
});
const { data: verifiedCredentials } = await this.client.post(
'/oauth/token',
params.toString()
);
const {
access_token: accessToken,
expires_in: expiresIn,
token_type: tokenType,
} = verifiedCredentials;
const { data: user } = await this.client.get('/me', {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
return {
consumerKey: this.connectionData.consumerKey,
consumerSecret: this.connectionData.consumerSecret,
accessToken,
expiresIn,
tokenType,
userId: user.user_id,
screenName: user.alias,
email: user.email,
};
}
async isStillVerified() {
try {
await this.client.get('/me', {
headers: {
Authorization: `Bearer ${this.connectionData.accessToken}`,
},
});
return true;
} catch {
return false;
}
}
}

View File

@@ -1,15 +0,0 @@
import Authentication from './authentication';
import {
IService,
IAuthentication,
IApp,
IJSONObject,
} from '@automatisch/types';
export default class Typeform implements IService {
authenticationClient: IAuthentication;
constructor(appData: IApp, connectionData: IJSONObject) {
this.authenticationClient = new Authentication(appData, connectionData);
}
}

View File

@@ -1,219 +0,0 @@
{
"name": "Typeform",
"key": "typeform",
"iconUrl": "{BASE_URL}/apps/typeform/assets/favicon.svg",
"docUrl": "https://automatisch.io/docs/typeform",
"primaryColor": "5865f2",
"supportsConnections": true,
"fields": [
{
"key": "oAuthRedirectUrl",
"label": "OAuth Redirect URL",
"type": "string",
"required": true,
"readOnly": true,
"value": "{WEB_APP_URL}/app/typeform/connections/add",
"placeholder": null,
"description": "When asked to input an OAuth callback or redirect URL in Typeform OAuth, enter the URL above.",
"docUrl": "https://automatisch.io/docs/typeform#oauth-redirect-url",
"clickToCopy": true
},
{
"key": "consumerKey",
"label": "Client ID",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/typeform#consumer-key",
"clickToCopy": false
},
{
"key": "consumerSecret",
"label": "Client Secret",
"type": "string",
"required": true,
"readOnly": false,
"value": null,
"placeholder": null,
"description": null,
"docUrl": "https://automatisch.io/docs/typeform#consumer-secret",
"clickToCopy": false
}
],
"authenticationSteps": [
{
"step": 1,
"type": "mutation",
"name": "createConnection",
"arguments": [
{
"name": "key",
"value": "{key}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "consumerKey",
"value": "{fields.consumerKey}"
},
{
"name": "consumerSecret",
"value": "{fields.consumerSecret}"
}
]
}
]
},
{
"step": 2,
"type": "mutation",
"name": "createAuthData",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
}
]
},
{
"step": 3,
"type": "openWithPopup",
"name": "openAuthPopup",
"arguments": [
{
"name": "url",
"value": "{createAuthData.url}"
}
]
},
{
"step": 4,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "oauthVerifier",
"value": "{openAuthPopup.code}"
}
]
}
]
},
{
"step": 5,
"type": "mutation",
"name": "verifyConnection",
"arguments": [
{
"name": "id",
"value": "{createConnection.id}"
}
]
}
],
"reconnectionSteps": [
{
"step": 1,
"type": "mutation",
"name": "resetConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
},
{
"step": 2,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "consumerKey",
"value": "{fields.consumerKey}"
},
{
"name": "consumerSecret",
"value": "{fields.consumerSecret}"
}
]
}
]
},
{
"step": 3,
"type": "mutation",
"name": "createAuthData",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
},
{
"step": 4,
"type": "openWithPopup",
"name": "openAuthPopup",
"arguments": [
{
"name": "url",
"value": "{createAuthData.url}"
}
]
},
{
"step": 5,
"type": "mutation",
"name": "updateConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
},
{
"name": "formattedData",
"value": null,
"properties": [
{
"name": "oauthVerifier",
"value": "{openAuthPopup.code}"
}
]
}
]
},
{
"step": 6,
"type": "mutation",
"name": "verifyConnection",
"arguments": [
{
"name": "id",
"value": "{connection.id}"
}
]
}
]
}

View File

@@ -102,13 +102,14 @@ class Processor {
priorExecutionSteps
);
step.parameters = computedParameters;
const clonedStep = Object.assign({}, step);
clonedStep.parameters = computedParameters;
const $ = await globalVariable(
step.connection,
app,
this.flow,
step,
clonedStep
);
if (!isTrigger && key) {

View File

@@ -1,6 +1,6 @@
{
"name": "@automatisch/cli",
"version": "0.1.4",
"version": "0.1.5",
"license": "AGPL-3.0",
"description": "The open source Zapier alternative. Build workflow automation without spending time and money.",
"contributors": [
@@ -33,7 +33,7 @@
"version": "oclif readme && git add README.md"
},
"dependencies": {
"@automatisch/backend": "^0.1.4",
"@automatisch/backend": "^0.1.5",
"@oclif/core": "^1",
"@oclif/plugin-help": "^5",
"@oclif/plugin-plugins": "^2.0.1",

View File

@@ -1,6 +1,6 @@
{
"name": "@automatisch/docs",
"version": "0.1.4",
"version": "0.1.5",
"license": "AGPL-3.0",
"description": "The open source Zapier alternative. Build workflow automation without spending time and money.",
"private": true,

View File

@@ -1,7 +1,7 @@
# Slack
:::info This page explains the steps you need to follow to set up the Slack
connection in Automatisch. If any of the steps are outdated, please let us know!
:::info
This page explains the steps you need to follow to set up the Slack connection in Automatisch. If any of the steps are outdated, please let us know!
:::
1. Go to the [link](https://api.slack.com/apps?new_app=1) to **create an app**

View File

@@ -0,0 +1 @@
TBD

View File

@@ -23,4 +23,4 @@ You can use `user@automatisch.io` email address and `sample` password to login t
:::
If you see any problems while installing Automatisch, let us know via [github issues](#) or our [discord server](https://discord.gg/dJSah9CVrC).
If you see any problems while installing Automatisch, let us know via [github issues](https://github.com/automatisch/automatisch/issues) or our [discord server](https://discord.gg/dJSah9CVrC).

View File

@@ -0,0 +1,17 @@
const { defineConfig } = require("cypress");
const TO_BE_PROVIDED = 'HAS_TO_BE_PROVIDED_IN_cypress.env.json';
module.exports = defineConfig({
e2e: {
baseUrl: 'http://localhost:3001',
env: {
login_email: "user@automatisch.io",
login_password: "sample",
slack_user_token: TO_BE_PROVIDED,
},
specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}',
viewportWidth: 1280,
viewportHeight: 768
},
});

View File

@@ -0,0 +1,50 @@
/// <reference types="cypress" />
describe('Apps page', () => {
before(() => {
cy.login();
cy.og('apps-page-drawer-link').click();
});
after(() => {
cy.logout();
});
it('displays applications', () => {
cy.og('apps-loader').should('not.exist');
cy.og('app-row').should('have.length', 3);
cy.ss('Applications');
});
context('can add connection', () => {
before(() => {
cy.og('add-connection-button').click();
});
it('lists applications', () => {
cy.og('app-list-item').should('have.length', 3);
});
it('searches an application', () => {
cy.og('search-for-app-text-field').type('Slack');
cy.og('app-list-item').should('have.length', 1);
});
it('goes to app page to create a connection', () => {
cy.og('app-list-item').first().click();
cy.location('pathname').should('equal', '/app/slack/connections/add');
cy.og('add-app-connection-dialog').should('be.visible');
});
it('closes the dialog on backdrop click', () => {
cy.clickOutside();
cy.location('pathname').should('equal', '/app/slack/connections');
cy.og('add-app-connection-dialog').should('not.exist');
});
});
});

View File

@@ -0,0 +1,52 @@
/// <reference types="cypress" />
describe('Connections page', () => {
before(() => {
cy.login();
cy.og('apps-page-drawer-link').click();
});
after(() => {
cy.logout();
});
it('opens via applications page', () => {
cy.og('apps-loader').should('not.exist');
cy.og('app-row').contains('Slack').click();
cy.og('app-connection-row').should('be.visible');
cy.ss('Slack connections before creating a connection');
});
context('can add connection', () => {
it('has a button to open add connection dialog', () => {
cy
.og('add-connection-button')
.scrollIntoView()
.should('be.visible');
});
it('add connection button takes user to add connection page', () => {
cy
.og('add-connection-button')
.click({ force: true });
cy.location('pathname').should('equal', '/app/slack/connections/add');
});
it('shows add connection dialog to create a new connection', () => {
cy
.get('input[name="accessToken"]')
.type(Cypress.env('slack_user_token'));
cy.og('create-connection-button').click();
cy.og('create-connection-button').should('not.exist');
cy.ss('Slack connections after creating a connection');
});
});
});

View File

@@ -0,0 +1,34 @@
/// <reference types="cypress" />
describe('Execution page', () => {
before(() => {
cy.login();
cy.og('executions-page-drawer-link').click();
cy.og('execution-row').first().click({ force: true });
cy.location('pathname').should('match', /^\/executions\//);
});
after(() => {
cy.logout();
});
it('displays data in by default', () => {
cy.og('execution-step').should('have.length', 2);
cy.ss('Execution - data in');
});
it('displays data out', () => {
cy.og('data-out-tab').click({ multiple: true });
cy.ss('Execution - data out');
});
it('displays error', () => {
cy.og('error-tab').click({ multiple: true, force: true });
cy.ss('Execution - error');
});
});

View File

@@ -0,0 +1,20 @@
/// <reference types="cypress" />
describe('Executions page', () => {
before(() => {
cy.login();
cy.og('executions-page-drawer-link').click();
});
after(() => {
cy.logout();
});
it('displays executions', () => {
cy.og('executions-loader').should('not.exist');
cy.og('execution-row').should('exist');
cy.ss('Executions');
});
});

View File

@@ -0,0 +1,229 @@
/// <reference types="cypress" />
describe('Flow editor page', () => {
before(() => {
cy.login();
});
after(() => {
cy.logout();
});
it('create flow', () => {
cy.og('create-flow-button').click({ force: true });
});
it('has two steps by default', () => {
cy.og('flow-step').should('have.length', 2);
});
context('edit flow', () => {
context('arrange Scheduler trigger', () => {
context('choose app and event substep', () => {
it('choose application', () => {
cy.og('choose-app-autocomplete').click();
cy.get('li[role="option"]:contains("Scheduler")').click();
});
it('choose an event', () => {
cy
.og('choose-event-autocomplete')
.should('be.visible')
.click();
cy.get('li[role="option"]:contains("Every hour")').click();
});
it('continue to next step', () => {
cy.og('flow-substep-continue-button').click();
});
it('collapses the substep', () => {
cy.og('choose-app-autocomplete').should('not.be.visible');
cy.og('choose-event-autocomplete').should('not.be.visible');
})
});
context('set up a trigger', () => {
it('choose "yes" in "trigger on weekends?"', () => {
cy
.og('parameters.triggersOnWeekend-autocomplete')
.should('be.visible')
.click();
cy.get('li[role="option"]:contains("Yes")').click();
});
it('continue to next step', () => {
cy.og('flow-substep-continue-button').click();
});
it('collapses the substep', () => {
cy.og('parameters.triggersOnWeekend-autocomplete').should('not.exist');
});
});
context('test trigger', () => {
it('show sample output', () => {
cy.og('flow-test-substep-output').should('not.exist');
cy.og('flow-substep-continue-button').click();
cy.og('flow-test-substep-output').should('be.visible');
cy.ss('Scheduler trigger test output');
cy.og('flow-substep-continue-button').click();
});
});
});
context('arrange Slack action', () => {
context('choose app and event substep', () => {
it('choose application', () => {
cy.og('choose-app-autocomplete').click();
cy.get('li[role="option"]:contains("Slack")').click();
});
it('choose an event', () => {
cy
.og('choose-event-autocomplete')
.should('be.visible')
.click();
cy.get('li[role="option"]:contains("Send a message to channel")').click();
});
it('continue to next step', () => {
cy.og('flow-substep-continue-button').click();
});
it('collapses the substep', () => {
cy.og('choose-app-autocomplete').should('not.be.visible');
cy.og('choose-event-autocomplete').should('not.be.visible');
});
});
context('choose connection', () => {
it('choose connection', () => {
cy.og('choose-connection-autocomplete').click();
cy.get('li[role="option"]').first().click();
});
it('continue to next step', () => {
cy.og('flow-substep-continue-button').click();
});
it('collapses the substep', () => {
cy.og('choose-connection-autocomplete').should('not.be.visible');
});
});
context('set up action', () => {
it('choose channel', () => {
cy.og('parameters.channel-autocomplete').click();
cy.get('li[role="option"]').last().click();
});
it('arrange message text', () => {
cy
.og('power-input', ' [contenteditable]')
.click()
.type(`Hello from e2e tests! Here is the first suggested variable's value; `);
cy
.og('power-input-suggestion-group').first()
.og('power-input-suggestion-item').first()
.click();
cy.clickOutside();
cy.ss('Slack action message text');
});
it('continue to next step', () => {
cy.og('flow-substep-continue-button').click();
});
it('collapses the substep', () => {
cy
.og('power-input', ' [contenteditable]')
.should('not.exist');
});
});
context('test trigger', () => {
it('show sample output', () => {
cy.og('flow-test-substep-output').should('not.exist');
cy.og('flow-substep-continue-button').click();
cy.og('flow-test-substep-output').should('be.visible');
cy.ss('Slack action test output');
cy.og('flow-substep-continue-button').click();
});
});
});
});
context('publish and unpublish', () => {
it('publish flow', () => {
cy.og('unpublish-flow-button').should('not.exist');
cy
.og('publish-flow-button')
.should('be.visible')
.click();
cy.og('publish-flow-button').should('not.exist');
});
it('shows read-only sticky snackbar', () => {
cy.og('flow-cannot-edit-info-snackbar').should('be.visible');
cy.ss('Published flow');
});
it('unpublish from snackbar', () => {
cy
.og('unpublish-flow-from-snackbar')
.click();
cy.og('flow-cannot-edit-info-snackbar').should('not.exist');
})
it('publish once again', () => {
cy
.og('publish-flow-button')
.should('be.visible')
.click();
cy.og('publish-flow-button').should('not.exist');
});
it('unpublish from layout top bar', () => {
cy
.og('unpublish-flow-button')
.should('be.visible')
.click();
cy.og('unpublish-flow-button').should('not.exist');
cy.ss('Unpublished flow');
});
});
context('in layout', () => {
it('can go back to flows page', () => {
cy.og('editor-go-back-button').click();
cy.location('pathname').should('equal', '/flows');
});
});
});

View File

@@ -0,0 +1,45 @@
Cypress.Commands.add('og', { prevSubject: 'optional' }, (subject, selector, suffix = '') => {
if (subject) {
return cy.wrap(subject).get(`[data-test="${selector}"]${suffix}`);
}
return cy.get(`[data-test="${selector}"]${suffix}`);
});
Cypress.Commands.add('login', () => {
cy.visit('/login');
cy.og('email-text-field').type(Cypress.env('login_email'));
cy.og('password-text-field').type(Cypress.env('login_password'));
cy
.intercept('/graphql')
.as('graphqlCalls');
cy
.intercept('https://notifications.automatisch.io/notifications.json')
.as('notificationsCall');
cy.og('login-button').click();
cy.wait(['@graphqlCalls', '@notificationsCall']);
});
Cypress.Commands.add('logout', () => {
cy.og('profile-menu-button').click();
cy.og('logout-item').click();
});
Cypress.Commands.add('ss', (name, opts = {}) => {
return cy.screenshot(
name,
{
overwrite: true,
capture: 'viewport',
...opts,
}
);
});
Cypress.Commands.add('clickOutside', () => {
return cy.get('body').click(0, 0);
});

View File

@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/e2e.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')

View File

@@ -0,0 +1,27 @@
{
"name": "@automatisch/e2e-tests",
"version": "0.1.5",
"license": "AGPL-3.0",
"private": true,
"description": "The open source Zapier alternative. Build workflow automation without spending time and money.",
"scripts": {
"open": "cypress open"
},
"contributors": [
{
"name": "automatisch contributors",
"url": "https://github.com/automatisch/automatisch/graphs/contributors"
}
],
"homepage": "https://github.com/automatisch/automatisch#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/automatisch/automatisch.git"
},
"bugs": {
"url": "https://github.com/automatisch/automatisch/issues"
},
"devDependencies": {
"cypress": "^10.9.0"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@automatisch/types",
"version": "0.1.4",
"version": "0.1.5",
"license": "AGPL-3.0",
"description": "Type definitions for automatisch",
"homepage": "https://github.com/automatisch/automatisch",

View File

@@ -1,11 +1,11 @@
{
"name": "@automatisch/web",
"version": "0.1.4",
"version": "0.1.5",
"license": "AGPL-3.0",
"description": "The open source Zapier alternative. Build workflow automation without spending time and money.",
"dependencies": {
"@apollo/client": "^3.6.9",
"@automatisch/types": "^0.1.4",
"@automatisch/types": "^0.1.5",
"@emotion/react": "^11.4.1",
"@emotion/styled": "^11.3.0",
"@hookform/resolvers": "^2.8.8",

View File

@@ -62,6 +62,7 @@ function AccountDropdownMenu(props: AccountDropdownMenuProps): React.ReactElemen
<MenuItem
onClick={logout}
data-test="logout-item"
>
{formatMessage('accountDropdownMenu.logout')}
</MenuItem>

View File

@@ -84,7 +84,7 @@ export default function AddAppConnection(props: AddAppConnectionProps): React.Re
}, [connectionId, key, steps, onClose]);
return (
<Dialog open={true} onClose={onClose}>
<Dialog open={true} onClose={onClose} data-test="add-app-connection-dialog">
<DialogTitle>{hasConnection ? formatMessage('app.reconnectConnection') : formatMessage('app.addConnection')}</DialogTitle>
<Alert severity="info" sx={{ fontWeight: 300 }}>
@@ -114,6 +114,7 @@ export default function AddAppConnection(props: AddAppConnectionProps): React.Re
color="primary"
sx={{ boxShadow: 2 }}
loading={inProgress}
data-test="create-connection-button"
>
{formatMessage('addAppConnection.submit')}
</LoadingButton>

View File

@@ -95,6 +95,7 @@ export default function AddNewAppConnection(props: AddNewAppConnectionProps): Re
</InputAdornment>
}
label={formatMessage('apps.searchApp')}
data-test="search-for-app-text-field"
/>
</FormControl>
@@ -102,7 +103,7 @@ export default function AddNewAppConnection(props: AddNewAppConnectionProps): Re
{loading && <CircularProgress sx={{ display: 'block', margin: '20px auto' }} />}
{!loading && data?.getApps?.map((app: IApp) => (
<ListItem disablePadding key={app.name}>
<ListItem disablePadding key={app.name} data-test="app-list-item">
<ListItemButton component={Link} to={createConnectionOrFlow(app.name.toLowerCase(), app.supportsConnections)}>
<ListItemIcon sx={{ minWidth: 74 }}>
<AppIcon color="transparent" url={app.iconUrl} name={app.name} />

View File

@@ -82,6 +82,7 @@ export default function AppBar(props: AppBarProps): React.ReactElement {
onClick={handleAccountMenuOpen}
aria-controls={accountMenuId}
aria-label="open profile menu"
data-test="profile-menu-button"
>
<AccountCircleIcon />
</IconButton>

View File

@@ -79,7 +79,7 @@ function AppConnectionRow(props: AppConnectionRowProps): React.ReactElement {
return (
<>
<Card sx={{ my: 2 }}>
<Card sx={{ my: 2 }} data-test="app-connection-row">
<CardActionArea onClick={onContextMenuClick}>
<CardContent>
<Stack

View File

@@ -30,7 +30,7 @@ function AppRow(props: AppRowProps): React.ReactElement {
const { name, primaryColor, iconUrl, connectionCount, flowCount } = props.application;
return (
<Link to={URLS.APP(name.toLowerCase())}>
<Link to={URLS.APP(name.toLowerCase())} data-test="app-row">
<Card sx={{ mb: 1 }}>
<CardActionArea>
<CardContent>

View File

@@ -152,6 +152,7 @@ function ChooseAppAndEventSubstep(
)}
value={getOption(appOptions, step.appKey)}
onChange={onAppChange}
data-test="choose-app-autocomplete"
/>
{step.appKey && (
@@ -175,6 +176,7 @@ function ChooseAppAndEventSubstep(
)}
value={getOption(actionOptions, step.key)}
onChange={onEventChange}
data-test="choose-event-autocomplete"
/>
</Box>
)}
@@ -197,6 +199,7 @@ function ChooseAppAndEventSubstep(
onClick={onSubmit}
sx={{ mt: 2 }}
disabled={!valid || editorContext.readOnly}
data-test="flow-substep-continue-button"
>
Continue
</Button>

View File

@@ -126,6 +126,7 @@ function ChooseConnectionSubstep(props: ChooseConnectionSubstepProps): React.Rea
value={getOption(connectionOptions, connection?.id)}
onChange={handleChange}
loading={loading}
data-test="choose-connection-autocomplete"
/>
<Button
@@ -133,7 +134,7 @@ function ChooseConnectionSubstep(props: ChooseConnectionSubstepProps): React.Rea
variant="contained"
onClick={onSubmit}
sx={{ mt: 2 }}
disabled={testResultLoading || !connection?.verified || editorContext.readOnly}
disabled={testResultLoading || !connection?.verified || editorContext.readOnly}data-test="flow-substep-continue-button"
>
Continue
</Button>

View File

@@ -55,6 +55,7 @@ function ControlledAutocomplete(props: ControlledAutocompleteProps): React.React
}}
onBlur={(...args) => { controllerOnBlur(); onBlur?.(...args); }}
ref={ref}
data-test={`${name}-autocomplete`}
/>
<FormHelperText

View File

@@ -18,6 +18,7 @@ type DrawerLink = {
primary: string;
to: string;
badgeContent?: React.ReactNode;
dataTest?: string;
};
type DrawerProps = {
@@ -49,13 +50,14 @@ export default function Drawer(props: DrawerProps): React.ReactElement {
<Toolbar />
<List sx={{ py: 0, mt: 3 }}>
{links.map(({ Icon, primary, to }, index) => (
{links.map(({ Icon, primary, to, dataTest }, index) => (
<ListItemLink
key={`${to}-${index}`}
icon={<Icon htmlColor={theme.palette.primary.main} />}
primary={formatMessage(primary)}
to={to}
onClick={closeOnClick}
data-test={dataTest}
/>
))}
</List>

View File

@@ -74,6 +74,7 @@ export default function EditorLayout(): React.ReactElement {
size="small"
component={Link}
to={URLS.FLOWS}
data-test="editor-go-back-button"
>
<ArrowBackIosNewIcon fontSize="small" />
</IconButton>
@@ -92,7 +93,12 @@ export default function EditorLayout(): React.ReactElement {
</Box>
<Box pr={1}>
<Button variant="contained" size="small" onClick={() => onFlowStatusUpdate(!flow.active)}>
<Button
variant="contained"
size="small"
onClick={() => onFlowStatusUpdate(!flow.active)}
data-test={flow?.active ? 'unpublish-flow-button' : 'publish-flow-button'}
>
{flow?.active ? formatMessage('flowEditor.unpublish') : formatMessage('flowEditor.publish')}
</Button>
</Box>
@@ -108,13 +114,19 @@ export default function EditorLayout(): React.ReactElement {
</Stack>
<Snackbar
data-test="flow-cannot-edit-info-snackbar"
open={!!flow?.active}
message={formatMessage('flowEditor.publishedFlowCannotBeUpdated')}
anchorOrigin={{ horizontal: 'center', vertical: 'bottom' }}
ContentProps={{ sx: { fontWeight: 300 }}}
action={(
<Button variant="contained" size="small" onClick={() => onFlowStatusUpdate(!flow.active)}>
{flow?.active ? formatMessage('flowEditor.unpublish') : formatMessage('flowEditor.publish')}
<Button
variant="contained"
size="small"
onClick={() => onFlowStatusUpdate(!flow.active)}
data-test="unpublish-flow-from-snackbar"
>
{formatMessage('flowEditor.unpublish')}
</Button>
)}
/>

View File

@@ -25,7 +25,7 @@ export default function ExecutionRow(props: ExecutionRowProps): React.ReactEleme
const relativeCreatedAt = createdAt.toRelative();
return (
<Link to={URLS.EXECUTION(execution.id)}>
<Link to={URLS.EXECUTION(execution.id)} data-test="execution-row">
<Card sx={{ mb: 1 }}>
<CardActionArea>
<CardContent>

View File

@@ -7,7 +7,7 @@ import Tabs from '@mui/material/Tabs';
import Tab from '@mui/material/Tab';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
import type { IApp, IJSONObject, IExecutionStep, IStep } from '@automatisch/types';
import type { IApp, IExecutionStep, IStep } from '@automatisch/types';
import TabPanel from 'components/TabPanel';
import JSONViewer from 'components/JSONViewer';
@@ -41,7 +41,7 @@ export default function ExecutionStep(props: ExecutionStepProps): React.ReactEle
const validationStatusIcon = executionStep.status === 'success' ? validIcon : errorIcon;
return (
<Wrapper elevation={1}>
<Wrapper elevation={1} data-test="execution-step">
<Header>
<Stack direction="row" alignItems="center" gap={2}>
<AppIconWrapper>
@@ -71,10 +71,9 @@ export default function ExecutionStep(props: ExecutionStepProps): React.ReactEle
<Content sx={{ px: 2 }}>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
<Tabs value={activeTabIndex} onChange={(event, tabIndex) => setActiveTabIndex(tabIndex)}>
<Tab label="Data in" />
<Tab label="Data out" />
<Tab label="Error" />
<Tab label="Execution step" />
<Tab label="Data in" data-test="data-in-tab" />
<Tab label="Data out" data-test="data-out-tab" />
<Tab label="Error" data-test="error-tab" />
</Tabs>
</Box>
@@ -89,10 +88,6 @@ export default function ExecutionStep(props: ExecutionStepProps): React.ReactEle
<TabPanel value={activeTabIndex} index={2}>
<JSONViewer data={executionStep.errorDetails} />
</TabPanel>
<TabPanel value={activeTabIndex} index={3}>
<JSONViewer data={(executionStep as unknown) as IJSONObject} />
</TabPanel>
</Content>
</Wrapper>

View File

@@ -182,7 +182,7 @@ export default function FlowStep(
step.status === 'completed' ? validIcon : errorIcon;
return (
<Wrapper elevation={collapsed ? 1 : 4} onClick={onOpen}>
<Wrapper elevation={collapsed ? 1 : 4} onClick={onOpen} data-test="flow-step">
<Header collapsed={collapsed}>
<Stack direction="row" alignItems="center" gap={2}>
<AppIconWrapper>

View File

@@ -100,6 +100,7 @@ function FlowSubstep(props: FlowSubstepProps): React.ReactElement {
sx={{ mt: 2 }}
disabled={!validationStatus || editorContext.readOnly}
type="submit"
data-test="flow-substep-continue-button"
>
Continue
</Button>

View File

@@ -22,16 +22,19 @@ const drawerLinks = [
Icon: SwapCallsIcon,
primary: 'drawer.flows',
to: URLS.FLOWS,
dataTest: 'flows-page-drawer-link',
},
{
Icon: AppsIcon,
primary: 'drawer.apps',
to: URLS.APPS,
dataTest: 'apps-page-drawer-link',
},
{
Icon: HistoryIcon,
primary: 'drawer.executions',
to: URLS.EXECUTIONS,
dataTest: 'executions-page-drawer-link',
},
];

View File

@@ -10,10 +10,11 @@ type ListItemLinkProps = {
primary: string;
to: string;
onClick?: (event: React.SyntheticEvent) => void;
'data-test'?: string;
}
export default function ListItemLink(props: ListItemLinkProps): React.ReactElement {
const { icon, primary, to, onClick } = props;
const { icon, primary, to, onClick, 'data-test': dataTest } = props;
const selected = useMatch({ path: to, end: true });
const CustomLink = React.useMemo(
@@ -34,6 +35,7 @@ export default function ListItemLink(props: ListItemLinkProps): React.ReactEleme
sx={{ pl: { xs: 2, sm: 3 } }}
selected={!!selected}
onClick={onClick}
data-test={dataTest}
>
<ListItemIcon sx={{ minWidth: 52 }}>{icon}</ListItemIcon>
<ListItemText primary={primary} primaryTypographyProps={{ variant: 'body1', }} />

View File

@@ -25,6 +25,7 @@ function renderFields(props: { loading: boolean }) {
fullWidth
margin="dense"
autoComplete="username"
data-test="email-text-field"
/>
<TextField
@@ -35,6 +36,7 @@ function renderFields(props: { loading: boolean }) {
fullWidth
margin="dense"
autoComplete="current-password"
data-test="password-text-field"
/>
<LoadingButton
@@ -44,6 +46,7 @@ function renderFields(props: { loading: boolean }) {
sx={{ boxShadow: 2, mt: 3 }}
loading={loading}
fullWidth
data-test="login-button"
>
Login
</LoadingButton>

View File

@@ -71,6 +71,7 @@ const Suggestions = (props: SuggestionsProps) => {
component="div"
disablePadding
sx={{ maxHeight: LIST_HEIGHT, overflowY: 'auto' }}
data-test="power-input-suggestion-group"
>
{getPartialArray((option.output as any) || [], listLength).map(
(suboption: any, index: number) => (
@@ -78,6 +79,8 @@ const Suggestions = (props: SuggestionsProps) => {
sx={{ pl: 4 }}
divider
onClick={() => onSuggestionClick(suboption)}
data-test="power-input-suggestion-item"
key={`suggestion-${suboption.name}`}
>
<ListItemText
primary={suboption.name}

View File

@@ -93,7 +93,7 @@ const PowerInput = (props: PowerInputProps) => {
onClickAway={() => { setShowVariableSuggestions(false); }}
>
{/* ref-able single child for ClickAwayListener */}
<div style={{ width: '100%' }}>
<div style={{ width: '100%' }} data-test="power-input">
<FakeInput disabled={disabled}>
<InputLabelWrapper>
<InputLabel

View File

@@ -106,7 +106,7 @@ function TestSubstep(props: TestSubstepProps): React.ReactElement {
)}
{response && (
<Box sx={{ maxHeight: 400, overflowY: 'auto', width: '100%' }}>
<Box sx={{ maxHeight: 400, overflowY: 'auto', width: '100%' }} data-test="flow-test-substep-output">
<JSONViewer data={response} />
</Box>
)}
@@ -119,6 +119,7 @@ function TestSubstep(props: TestSubstepProps): React.ReactElement {
loading={loading}
disabled={editorContext.readOnly}
color="primary"
data-test="flow-substep-continue-button"
>
{isCompleted && formatMessage('flowEditor.continue')}
{!isCompleted && formatMessage('flowEditor.testAndContinue')}

View File

@@ -126,6 +126,7 @@ export default function Application(): React.ReactElement | null {
component={NewConnectionLink}
fullWidth
icon={<AddIcon />}
data-test="add-connection-button"
>
{formatMessage('app.addConnection')}
</ConditionalIconButton>

View File

@@ -69,6 +69,7 @@ export default function Applications(): React.ReactElement {
component={NewAppConnectionLink}
fullWidth
icon={<AddIcon />}
data-test="add-connection-button"
>
{formatMessage('apps.addConnection')}
</ConditionalIconButton>
@@ -77,7 +78,7 @@ export default function Applications(): React.ReactElement {
<Divider sx={{ mt: [2, 0], mb: 2 }} />
{loading && <CircularProgress sx={{ display: 'block', margin: '20px auto' }} />}
{loading && <CircularProgress data-test="apps-loader" sx={{ display: 'block', margin: '20px auto' }} />}
{!loading && !hasApps && (<NoResultFound
text={formatMessage('apps.noConnections')}

View File

@@ -54,7 +54,7 @@ export default function Executions(): React.ReactElement {
<Divider sx={{ mt: [2, 0], mb: 2 }} />
{loading && <CircularProgress sx={{ display: 'block', margin: '20px auto' }} />}
{loading && <CircularProgress data-test="executions-loader" sx={{ display: 'block', margin: '20px auto' }} />}
{!loading && !hasExecutions && (<NoResultFound
text={formatMessage('executions.noExecutions')}

View File

@@ -110,6 +110,7 @@ export default function Flows(): React.ReactElement {
component={CreateFlowLink}
fullWidth
icon={<AddIcon />}
data-test="create-flow-button"
>
{formatMessage('flows.create')}
</ConditionalIconButton>

View File

@@ -11,23 +11,29 @@
jsonpointer "^5.0.0"
leven "^3.1.0"
"@apollo/client@^3.4.15":
version "3.5.6"
resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.5.6.tgz#911929df073280689efd98e5603047b79e0c39a2"
integrity sha512-XHoouuEJ4L37mtfftcHHO1caCRrKKAofAwqRoq28UQIPMJk+e7n3X9OtRRNXKk/9tmhNkwelSary+EilfPwI7A==
"@apollo/client@^3.6.9":
version "3.7.0"
resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.7.0.tgz#1c26a04488f45b3a4779fa2562e4b706402cb876"
integrity sha512-hp4OvrH1ZIQACRYcIrh/C0WFnY7IM7G6nlTpC8DSTEWxfZQ2kvpvDY0I/hYmCs0oAVrg26g3ANEdOzGWTcYbPg==
dependencies:
"@graphql-typed-document-node/core" "^3.0.0"
"@wry/context" "^0.6.0"
"@graphql-typed-document-node/core" "^3.1.1"
"@wry/context" "^0.7.0"
"@wry/equality" "^0.5.0"
"@wry/trie" "^0.3.0"
graphql-tag "^2.12.3"
graphql-tag "^2.12.6"
hoist-non-react-statics "^3.3.2"
optimism "^0.16.1"
prop-types "^15.7.2"
response-iterator "^0.2.6"
symbol-observable "^4.0.0"
ts-invariant "^0.9.4"
ts-invariant "^0.10.3"
tslib "^2.3.0"
zen-observable-ts "^1.2.0"
zen-observable-ts "^1.2.5"
"@automatisch/types@^0.1.4":
version "0.1.4"
resolved "https://registry.yarnpkg.com/@automatisch/types/-/types-0.1.4.tgz#30c813bbd68937ed2f4a74651a07284f2d925d62"
integrity sha512-vc1bjz2VTWvxQPtC4yHp7t+TA5lpZXKeVLTiT385wxIGsgPgE2kDrlWp5FCea8Adk4MRn90BEWD5cDzLd+7OtA==
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13":
version "7.12.13"
@@ -1790,6 +1796,13 @@
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.15.4", "@babel/runtime@^7.16.7", "@babel/runtime@^7.17.8":
version "7.19.0"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259"
integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==
dependencies:
regenerator-runtime "^0.13.4"
"@babel/template@^7.12.13", "@babel/template@^7.3.3":
version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327"
@@ -2085,11 +2098,16 @@
intl-messageformat "9.10.0"
tslib "^2.1.0"
"@graphql-typed-document-node/core@^3.0.0":
"@graphql-typed-document-node/core@^3.1.1":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.1.1.tgz#076d78ce99822258cf813ecc1e7fa460fa74d052"
integrity sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==
"@hookform/resolvers@^2.8.8":
version "2.9.8"
resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-2.9.8.tgz#9af51d15602f3c6e3249714712d8275564e65b72"
integrity sha512-iVVjH0USq+1TqDdGkWe2M1x7Wn5OFPgVRo7CbWFsXTqqXqCaZtZcnzJu+UhljCWbthFWxWGXKLGYUDPZ04oVvQ==
"@humanwhocodes/config-array@^0.9.2":
version "0.9.3"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.3.tgz#f2564c744b387775b436418491f15fce6601f63e"
@@ -2769,6 +2787,11 @@
dependencies:
"@babel/types" "^7.3.0"
"@types/base16@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@types/base16/-/base16-1.0.2.tgz#eb3a07db52309bfefb9ba010dfdb3c0784971f65"
integrity sha512-oYO/U4VD1DavwrKuCSQWdLG+5K22SLPem2OQaHmFcQuwHoVeGC+JGVRji2MUqZUAIQZHEonOeVfAX09hYiLsdg==
"@types/body-parser@*":
version "1.19.2"
resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0"
@@ -2884,6 +2907,11 @@
dependencies:
"@types/node" "*"
"@types/is-hotkey@^0.1.1":
version "0.1.7"
resolved "https://registry.yarnpkg.com/@types/is-hotkey/-/is-hotkey-0.1.7.tgz#30ec6d4234895230b576728ef77e70a52962f3b3"
integrity sha512-yB5C7zcOM7idwYZZ1wKQ3pTfjA9BbvFqRWvKB46GFddxnJtHwi/b9y84ykQtxQPg5qhdpg4Q/kWU3EGoCTmLzQ==
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762"
@@ -2934,17 +2962,10 @@
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
"@types/lodash.template@^4.5.0":
version "4.5.0"
resolved "https://registry.yarnpkg.com/@types/lodash.template/-/lodash.template-4.5.0.tgz#277654af717ed37ce2687c69f8f221c550276b7a"
integrity sha512-4LgHxK16IPbGR7TmXpPvNT7iNGsLCdQY6Rc0mi1a/JECt8et/D4hx6NMVAJej/d932sj1mJsg0QYHKL189O0Qw==
dependencies:
"@types/lodash" "*"
"@types/lodash@*":
version "4.14.178"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.178.tgz#341f6d2247db528d4a13ddbb374bcdc80406f4f8"
integrity sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==
"@types/lodash@^4.14.149", "@types/lodash@^4.14.175", "@types/lodash@^4.14.178", "@types/lodash@^4.14.182":
version "4.14.186"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.186.tgz#862e5514dd7bd66ada6c70ee5fce844b06c8ee97"
integrity sha512-eHcVlLXP0c2FlMPm56ITode2AgLMSa6aJ05JTTbYbI+7EMkCEE5qk2E41d5g2lCVTqRe0GnnRFurmlCsDODrPw==
"@types/luxon@^2.0.8":
version "2.0.8"
@@ -3332,6 +3353,13 @@
dependencies:
tslib "^2.3.0"
"@wry/context@^0.7.0":
version "0.7.0"
resolved "https://registry.yarnpkg.com/@wry/context/-/context-0.7.0.tgz#be88e22c0ddf62aeb0ae9f95c3d90932c619a5c8"
integrity sha512-LcDAiYWRtwAoSOArfk7cuYvFXytxfVrdX7yxoUmK7pPITLk5jYh2F8knCwS7LjgYL8u1eidPlKKV6Ikqq0ODqQ==
dependencies:
tslib "^2.3.0"
"@wry/equality@^0.5.0":
version "0.5.2"
resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.5.2.tgz#72c8a7a7d884dff30b612f4f8464eba26c080e73"
@@ -3625,18 +3653,18 @@ ast-types-flow@^0.0.7:
resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0=
async@0.9.x:
version "0.9.2"
resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d"
integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=
async@^2.6.2:
version "2.6.3"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
version "2.6.4"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==
dependencies:
lodash "^4.17.14"
async@^3.2.3:
version "3.2.4"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c"
integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@@ -3827,9 +3855,14 @@ babel-preset-react-app@^10.0.1:
babel-plugin-transform-react-remove-prop-types "^0.4.24"
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
base16@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
resolved "https://registry.yarnpkg.com/base16/-/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70"
integrity sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==
batch@0.6.1:
version "0.6.1"
@@ -3902,6 +3935,13 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0"
concat-map "0.0.1"
brace-expansion@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
dependencies:
balanced-match "^1.0.0"
braces@^3.0.1, braces@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
@@ -4018,7 +4058,7 @@ case-sensitive-paths-webpack-plugin@^2.4.0:
resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4"
integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==
chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2:
chalk@^2.0.0, chalk@^2.4.1:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@@ -4035,7 +4075,7 @@ chalk@^3.0.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2:
chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
@@ -4140,7 +4180,7 @@ collect-v8-coverage@^1.0.0:
resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59"
integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==
color-convert@^1.9.0:
color-convert@^1.9.0, color-convert@^1.9.3:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
@@ -4159,11 +4199,27 @@ color-name@1.1.3:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
color-name@^1.1.4, color-name@~1.1.4:
color-name@^1.0.0, color-name@^1.1.4, color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
color-string@^1.6.0:
version "1.9.1"
resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4"
integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==
dependencies:
color-name "^1.0.0"
simple-swizzle "^0.2.2"
color@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164"
integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==
dependencies:
color-convert "^1.9.3"
color-string "^1.6.0"
colord@^2.9.1:
version "2.9.2"
resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.2.tgz#25e2bacbbaa65991422c07ea209e2089428effb1"
@@ -4211,6 +4267,11 @@ commondir@^1.0.1:
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
compare-versions@^4.1.3:
version "4.1.4"
resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-4.1.4.tgz#3571f4d610924d4414846a4183d386c8f3d51112"
integrity sha512-FemMreK9xNyL8gQevsdRMrvO4lFCkQP7qbuktn1q8ndcNk1+0mz7lgE7b/sNvbhVgY4w6tMN1FDp6aADjqw2rw==
compressible@~2.0.16:
version "2.0.18"
resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba"
@@ -4231,10 +4292,15 @@ compression@^1.7.4:
safe-buffer "5.1.2"
vary "~1.1.2"
compute-scroll-into-view@^1.0.17:
version "1.0.17"
resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.17.tgz#6a88f18acd9d42e9cf4baa6bec7e0522607ab7ab"
integrity sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg==
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
confusing-browser-globals@^1.0.11:
version "1.0.11"
@@ -4770,6 +4836,11 @@ dir-glob@^3.0.1:
dependencies:
path-type "^4.0.0"
direction@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/direction/-/direction-1.0.4.tgz#2b86fb686967e987088caf8b89059370d4837442"
integrity sha512-GYqKi1aH7PJXxdhTeZBFrg8vUBeKXi+cNprXsC1kpJcbcVnV9wBsrOu1cQEdG0WeQwlfHiy3XvnKfIrJ2R0NzQ==
dlv@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79"
@@ -4921,11 +4992,11 @@ ee-first@1.1.1:
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
ejs@^3.1.6:
version "3.1.6"
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.6.tgz#5bfd0a0689743bb5268b3550cceeebbc1702822a"
integrity sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==
version "3.1.8"
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.8.tgz#758d32910c78047585c7ef1f92f9ee041c1c190b"
integrity sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==
dependencies:
jake "^10.6.1"
jake "^10.8.5"
electron-to-chromium@^1.4.17:
version "1.4.56"
@@ -5517,11 +5588,11 @@ file-loader@^6.2.0:
schema-utils "^3.0.0"
filelist@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.2.tgz#80202f21462d4d1c2e214119b1807c1bc0380e5b"
integrity sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==
version "1.0.4"
resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5"
integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==
dependencies:
minimatch "^3.0.4"
minimatch "^5.0.1"
filesize@^8.0.6:
version "8.0.7"
@@ -5605,7 +5676,7 @@ flatted@^3.1.0:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469"
integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==
follow-redirects@1.14.8, follow-redirects@^1.0.0:
follow-redirects@^1.0.0:
version "1.14.8"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc"
integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==
@@ -5832,7 +5903,7 @@ graceful-fs@^4.2.6, graceful-fs@^4.2.9:
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96"
integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==
graphql-tag@^2.12.3:
graphql-tag@^2.12.6:
version "2.12.6"
resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1"
integrity sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==
@@ -6115,6 +6186,11 @@ ignore@^5.1.8, ignore@^5.2.0:
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
immer@^9.0.6:
version "9.0.15"
resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.15.tgz#0b9169e5b1d22137aba7d43f8a81a495dd1b62dc"
integrity sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==
immer@^9.0.7:
version "9.0.12"
resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.12.tgz#2d33ddf3ee1d247deab9d707ca472c8c942a0f20"
@@ -6220,6 +6296,11 @@ is-arrayish@^0.2.1:
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
is-arrayish@^0.3.1:
version "0.3.2"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
is-bigint@^1.0.1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3"
@@ -6303,6 +6384,11 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
dependencies:
is-extglob "^2.1.1"
is-hotkey@^0.1.6:
version "0.1.8"
resolved "https://registry.yarnpkg.com/is-hotkey/-/is-hotkey-0.1.8.tgz#6b1f4b2d0e5639934e20c05ed24d623a21d36d25"
integrity sha512-qs3NZ1INIS+H+yeo7cD9pDfwYV/jqRh1JG9S9zYrNudkoUQg7OL7ziXqRKu+InFjUIDoP2o6HIkLYMh1pcWgyQ==
is-module@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
@@ -6345,6 +6431,11 @@ is-plain-obj@^3.0.0:
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7"
integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==
is-plain-object@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344"
integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==
is-potential-custom-element-name@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5"
@@ -6488,13 +6579,13 @@ istanbul-reports@^3.1.3:
html-escaper "^2.0.0"
istanbul-lib-report "^3.0.0"
jake@^10.6.1:
version "10.8.2"
resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.2.tgz#ebc9de8558160a66d82d0eadc6a2e58fbc500a7b"
integrity sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==
jake@^10.8.5:
version "10.8.5"
resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46"
integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==
dependencies:
async "0.9.x"
chalk "^2.4.2"
async "^3.2.3"
chalk "^4.0.2"
filelist "^1.0.1"
minimatch "^3.0.4"
@@ -7212,10 +7303,15 @@ locate-path@^6.0.0:
dependencies:
p-locate "^5.0.0"
lodash._reinterpolate@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=
lodash-es@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
lodash.curry@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.curry/-/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170"
integrity sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==
lodash.debounce@^4.0.8:
version "4.0.8"
@@ -7237,27 +7333,12 @@ lodash.sortby@^4.7.0:
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
lodash.template@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"
integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==
dependencies:
lodash._reinterpolate "^3.0.0"
lodash.templatesettings "^4.0.0"
lodash.templatesettings@^4.0.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33"
integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==
dependencies:
lodash._reinterpolate "^3.0.0"
lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0:
lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -7283,10 +7364,10 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
luxon@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/luxon/-/luxon-2.2.0.tgz#f5c4a234ba4016f792488b11aaed2d5bc14c888e"
integrity sha512-LwmknessH4jVIseCsizUgveIHwlLv/RQZWC2uDSMfGJs7w8faPUi2JFxfyfMcTPrpNbChTem3Uz6IKRtn+LcIA==
luxon@^2.3.1:
version "2.5.0"
resolved "https://registry.yarnpkg.com/luxon/-/luxon-2.5.0.tgz#098090f67d690b247e83c090267a60b1aa8ea96c"
integrity sha512-IDkEPB80Rb6gCAU+FEib0t4FeJ4uVOuX1CQ9GsvU3O+JAGIgu0J7sf1OarXKaKDygTZIoJyU6YdZzTFRu+YR0A==
lz-string@^1.4.4:
version "1.4.4"
@@ -7423,14 +7504,28 @@ minimalistic-assert@^1.0.0:
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
minimatch@3.0.4, minimatch@^3.0.4:
minimatch@3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
dependencies:
brace-expansion "^1.1.7"
minimist@1.2.6, minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5:
minimatch@^3.0.4:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
minimatch@^5.0.1:
version "5.1.0"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7"
integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==
dependencies:
brace-expansion "^2.0.1"
minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5:
version "1.2.6"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
@@ -7475,6 +7570,11 @@ multicast-dns@^6.0.1:
dns-packet "^1.3.1"
thunky "^1.0.2"
nanoclone@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/nanoclone/-/nanoclone-0.2.1.tgz#dd4090f8f1a110d26bb32c49ed2f5b9235209ed4"
integrity sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==
nanoid@^3.1.30:
version "3.2.0"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c"
@@ -7503,7 +7603,7 @@ no-case@^3.0.4:
lower-case "^2.0.2"
tslib "^2.0.3"
node-forge@1.3.0, node-forge@^1.2.0:
node-forge@^1.2.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.0.tgz#37a874ea723855f37db091e6c186e5b67a01d4b2"
integrity sha512-08ARB91bUi6zNKzVmaj3QO7cr397uiDT2nJ63cHjyNtCTWIgvS47j3eT0WfzUwS9+6Z5YshRaoasFkXCKrIYbA==
@@ -8552,6 +8652,20 @@ prop-types@^15.6.2, prop-types@^15.7.2:
object-assign "^4.1.1"
react-is "^16.8.1"
prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
dependencies:
loose-envify "^1.4.0"
object-assign "^4.1.1"
react-is "^16.13.1"
property-expr@^2.0.4:
version "2.0.5"
resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.5.tgz#278bdb15308ae16af3e3b9640024524f4dc02cb4"
integrity sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==
proxy-addr@~2.0.5:
version "2.0.6"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf"
@@ -8631,6 +8745,19 @@ react-app-polyfill@^3.0.0:
regenerator-runtime "^0.13.9"
whatwg-fetch "^3.6.2"
react-base16-styling@^0.9.1:
version "0.9.1"
resolved "https://registry.yarnpkg.com/react-base16-styling/-/react-base16-styling-0.9.1.tgz#4906b4c0a51636f2dca2cea8b682175aa8bd0c92"
integrity sha512-1s0CY1zRBOQ5M3T61wetEpvQmsYSNtWEcdYzyZNxKa8t7oDvaOn9d21xrGezGAHFWLM7SHcktPuPTrvoqxSfKw==
dependencies:
"@babel/runtime" "^7.16.7"
"@types/base16" "^1.0.2"
"@types/lodash" "^4.14.178"
base16 "^1.0.0"
color "^3.2.1"
csstype "^3.0.10"
lodash.curry "^4.1.1"
react-dev-utils@^12.0.0:
version "12.0.0"
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-12.0.0.tgz#4eab12cdb95692a077616770b5988f0adf806526"
@@ -8696,7 +8823,7 @@ react-intl@^5.20.12:
intl-messageformat "9.10.0"
tslib "^2.1.0"
react-is@^16.7.0, react-is@^16.8.1:
react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
@@ -8711,6 +8838,16 @@ react-is@^17.0.2:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
react-json-tree@^0.16.2:
version "0.16.2"
resolved "https://registry.yarnpkg.com/react-json-tree/-/react-json-tree-0.16.2.tgz#697bd9413407d2448ddff3c8891cd4395342539e"
integrity sha512-80F7ZTqeOl1YaS/sDce4tYBcSe69/d0mlUmcIhyXezPFctWrtvyN56EMExX9jWsq3XMdvsUKKPUeNo8QCBy2jg==
dependencies:
"@babel/runtime" "^7.17.8"
"@types/prop-types" "^15.7.4"
prop-types "^15.8.1"
react-base16-styling "^0.9.1"
react-refresh@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046"
@@ -9008,6 +9145,11 @@ resolve@^2.0.0-next.3:
is-core-module "^2.2.0"
path-parse "^1.0.6"
response-iterator@^0.2.6:
version "0.2.6"
resolved "https://registry.yarnpkg.com/response-iterator/-/response-iterator-0.2.6.tgz#249005fb14d2e4eeb478a3f735a28fd8b4c9f3da"
integrity sha512-pVzEEzrsg23Sh053rmDUvLSkGXluZio0qu8VT6ukrYuvtjVfCbDZH9d6PGXb8HZfzdNZt8feXv/jvUzlhRgLnw==
retry@^0.13.1:
version "0.13.1"
resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658"
@@ -9148,6 +9290,13 @@ schema-utils@^4.0.0:
ajv-formats "^2.1.1"
ajv-keywords "^5.0.0"
scroll-into-view-if-needed@^2.2.20:
version "2.2.29"
resolved "https://registry.yarnpkg.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.29.tgz#551791a84b7e2287706511f8c68161e4990ab885"
integrity sha512-hxpAR6AN+Gh53AdAimHM6C8oTN1ppwVZITihix+WqalywBeFcQ6LdQP5ABNl26nX8GTEL7VT+b8lKpdqq65wXg==
dependencies:
compute-scroll-into-view "^1.0.17"
select-hose@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
@@ -9291,6 +9440,13 @@ signal-exit@^3.0.3:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af"
integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==
simple-swizzle@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==
dependencies:
is-arrayish "^0.3.1"
sisteransi@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed"
@@ -9306,6 +9462,36 @@ slash@^4.0.0:
resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7"
integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==
slate-history@^0.66.0:
version "0.66.0"
resolved "https://registry.yarnpkg.com/slate-history/-/slate-history-0.66.0.tgz#ac63fddb903098ceb4c944433e3f75fe63acf940"
integrity sha512-6MWpxGQZiMvSINlCbMW43E2YBSVMCMCIwQfBzGssjWw4kb0qfvj0pIdblWNRQZD0hR6WHP+dHHgGSeVdMWzfng==
dependencies:
is-plain-object "^5.0.0"
slate-react@^0.72.9:
version "0.72.9"
resolved "https://registry.yarnpkg.com/slate-react/-/slate-react-0.72.9.tgz#b05dd533bd29dd2d4796b614a8d8e01f214bb714"
integrity sha512-FEsqB+D1R/h+w1eCtHH367Krw2X7vju2GjMRL/d0bUiCRXlV50J9I9TJizvi7aaZyqBY8BypCuIiq9nNmsulCA==
dependencies:
"@types/is-hotkey" "^0.1.1"
"@types/lodash" "^4.14.149"
direction "^1.0.3"
is-hotkey "^0.1.6"
is-plain-object "^5.0.0"
lodash "^4.17.4"
scroll-into-view-if-needed "^2.2.20"
tiny-invariant "1.0.6"
slate@^0.72.8:
version "0.72.8"
resolved "https://registry.yarnpkg.com/slate/-/slate-0.72.8.tgz#5a018edf24e45448655293a68bfbcf563aa5ba81"
integrity sha512-/nJwTswQgnRurpK+bGJFH1oM7naD5qDmHd89JyiKNT2oOKD8marW0QSBtuFnwEbL5aGCS8AmrhXQgNOsn4osAw==
dependencies:
immer "^9.0.6"
is-plain-object "^5.0.0"
tiny-warning "^1.0.3"
sockjs@^0.3.21:
version "0.3.21"
resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417"
@@ -9355,7 +9541,7 @@ source-map-url@^0.4.0:
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56"
integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==
source-map@0.6.1, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
@@ -9365,12 +9551,7 @@ source-map@^0.5.0, source-map@^0.5.7:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
source-map@^0.6.0:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
source-map@^0.7.3, source-map@~0.7.2:
source-map@^0.7.3:
version "0.7.3"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
@@ -9758,7 +9939,7 @@ terser-webpack-plugin@^5.1.3, terser-webpack-plugin@^5.2.5:
source-map "^0.6.1"
terser "^5.7.2"
terser@5.14.2, terser@^5.0.0, terser@^5.10.0, terser@^5.7.2:
terser@^5.0.0, terser@^5.10.0, terser@^5.7.2:
version "5.14.2"
resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10"
integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==
@@ -9797,6 +9978,16 @@ timsort@^0.3.0:
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
tiny-invariant@1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.0.6.tgz#b3f9b38835e36a41c843a3b0907a5a7b3755de73"
integrity sha512-FOyLWWVjG+aC0UqG76V53yAWdXfH8bO6FNmyZOuUrzDzK8DI3/JRY25UD7+g49JWM1LXwymsKERB+DzI0dTEQA==
tiny-warning@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
tmpl@1.0.x:
version "1.0.5"
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"
@@ -9819,6 +10010,11 @@ toidentifier@1.0.0:
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
toposort@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330"
integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==
tough-cookie@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4"
@@ -9854,10 +10050,10 @@ tryer@^1.0.1:
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==
ts-invariant@^0.9.4:
version "0.9.4"
resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.9.4.tgz#42ac6c791aade267dd9dc65276549df5c5d71cac"
integrity sha512-63jtX/ZSwnUNi/WhXjnK8kz4cHHpYS60AnmA6ixz17l7E12a5puCWFlNpkne5Rl0J8TBPVHpGjsj4fxs8ObVLQ==
ts-invariant@^0.10.3:
version "0.10.3"
resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.10.3.tgz#3e048ff96e91459ffca01304dbc7f61c1f642f6c"
integrity sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==
dependencies:
tslib "^2.1.0"
@@ -9942,10 +10138,10 @@ typedarray-to-buffer@^3.1.5:
dependencies:
is-typedarray "^1.0.0"
typescript@^4.1.2:
version "4.4.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.3.tgz#bdc5407caa2b109efd4f82fe130656f977a29324"
integrity sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==
typescript@^4.6.3:
version "4.8.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6"
integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==
unbox-primitive@^1.0.1:
version "1.0.1"
@@ -10585,10 +10781,23 @@ yocto-queue@^0.1.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
zen-observable-ts@^1.2.0:
version "1.2.3"
resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.2.3.tgz#c2f5ccebe812faf0cfcde547e6004f65b1a6d769"
integrity sha512-hc/TGiPkAWpByykMwDcem3SdUgA4We+0Qb36bItSuJC9xD0XVBZoFHYoadAomDSNf64CG8Ydj0Qb8Od8BUWz5g==
yup@^0.32.11:
version "0.32.11"
resolved "https://registry.yarnpkg.com/yup/-/yup-0.32.11.tgz#d67fb83eefa4698607982e63f7ca4c5ed3cf18c5"
integrity sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==
dependencies:
"@babel/runtime" "^7.15.4"
"@types/lodash" "^4.14.175"
lodash "^4.17.21"
lodash-es "^4.17.21"
nanoclone "^0.2.1"
property-expr "^2.0.4"
toposort "^2.0.2"
zen-observable-ts@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz#6c6d9ea3d3a842812c6e9519209365a122ba8b58"
integrity sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==
dependencies:
zen-observable "0.8.15"