Merge pull request #616 from automatisch/add-define-app-and-before-request

feat: add defineApp and beforeRequest
This commit is contained in:
Ömer Faruk Aydın
2022-10-18 00:34:56 +02:00
committed by GitHub
7 changed files with 60 additions and 21 deletions

View File

@@ -0,0 +1,11 @@
import { TBeforeRequest } from "@automatisch/types";
const addAuthHeader: TBeforeRequest = ($, requestConfig) => {
if (requestConfig.headers && $.auth.data?.accessToken) {
requestConfig.headers.Authorization = `Bearer ${$.auth.data.accessToken}`
}
return requestConfig;
}
export default addAuthHeader;

View File

@@ -1,4 +1,7 @@
export default { import defineApp from '../../helpers/define-app';
import addAuthHeader from './common/add-auth-header';
export default defineApp({
name: 'Github', name: 'Github',
key: 'github', key: 'github',
baseUrl: 'https://github.com', baseUrl: 'https://github.com',
@@ -7,4 +10,5 @@ export default {
authDocUrl: 'https://automatisch.io/docs/connections/github', authDocUrl: 'https://automatisch.io/docs/connections/github',
primaryColor: '000000', primaryColor: '000000',
supportsConnections: true, supportsConnections: true,
}; beforeRequest: [addAuthHeader],
});

View File

@@ -0,0 +1,5 @@
import { IApp } from '@automatisch/types';
export default function defineApp(appDefinition: IApp): IApp {
return appDefinition;
}

View File

@@ -24,7 +24,7 @@ const globalVariable = async (
const trigger = await step?.getTriggerCommand(); const trigger = await step?.getTriggerCommand();
const nextStep = await step?.getNextStep(); const nextStep = await step?.getNextStep();
const variable: IGlobalVariable = { const $: IGlobalVariable = {
auth: { auth: {
set: async (args: IJSONObject) => { set: async (args: IJSONObject) => {
if (connection) { if (connection) {
@@ -41,7 +41,6 @@ const globalVariable = async (
data: connection?.formattedData, data: connection?.formattedData,
}, },
app: app, app: app,
http: createHttpClient({ baseURL: app.apiBaseUrl }),
flow: { flow: {
id: flow?.id, id: flow?.id,
lastInternalId, lastInternalId,
@@ -62,6 +61,12 @@ const globalVariable = async (
}, },
}; };
$.http = createHttpClient({
$,
baseURL: app.apiBaseUrl,
beforeRequest: app.beforeRequest,
});
if (trigger && trigger.dedupeStrategy === 'unique') { if (trigger && trigger.dedupeStrategy === 'unique') {
const lastInternalIds = await flow?.lastInternalIds(); const lastInternalIds = await flow?.lastInternalIds();
@@ -69,10 +74,10 @@ const globalVariable = async (
return lastInternalIds?.includes(internalId); return lastInternalIds?.includes(internalId);
}; };
variable.flow.isAlreadyProcessed = isAlreadyProcessed; $.flow.isAlreadyProcessed = isAlreadyProcessed;
} }
return variable; return $;
}; };
export default globalVariable; export default globalVariable;

View File

@@ -1,12 +1,18 @@
import axios from 'axios'; import axios, { AxiosRequestConfig } from 'axios';
export { AxiosInstance as IHttpClient } from 'axios'; export { AxiosInstance as IHttpClient } from 'axios';
import { IHttpClientParams } from '@automatisch/types'; import { IHttpClientParams } from '@automatisch/types';
export default function createHttpClient({ baseURL }: IHttpClientParams) { export default function createHttpClient({ $, baseURL, beforeRequest = [] }: IHttpClientParams) {
const instance = axios.create({ const instance = axios.create({
baseURL, baseURL,
}); });
instance.interceptors.request.use((requestConfig: AxiosRequestConfig): AxiosRequestConfig => {
return beforeRequest.reduce((newConfig, beforeRequestFunc) => {
return beforeRequestFunc($, newConfig);
}, requestConfig);
});
instance.interceptors.response.use( instance.interceptors.response.use(
(response) => response, (response) => response,
(error) => { (error) => {

View File

@@ -1,4 +1,4 @@
import type { AxiosInstance } from 'axios'; import type { AxiosInstance, AxiosRequestConfig } from 'axios';
export type IHttpClient = AxiosInstance; export type IHttpClient = AxiosInstance;
// Type definitions for automatisch // Type definitions for automatisch
@@ -153,19 +153,24 @@ export interface IApp {
name: string; name: string;
key: string; key: string;
iconUrl: string; iconUrl: string;
docUrl: string; docUrl?: string;
authDocUrl: string; authDocUrl: string;
primaryColor: string; primaryColor: string;
supportsConnections: boolean; supportsConnections: boolean;
apiBaseUrl: string; apiBaseUrl: string;
baseUrl: string; baseUrl: string;
auth: IAuth; auth?: IAuth;
connectionCount: number; connectionCount?: number;
flowCount: number; flowCount?: number;
data: IData; beforeRequest: TBeforeRequest[];
triggers: ITrigger[]; data?: IData;
actions: IAction[]; triggers?: ITrigger[];
connections: IConnection[]; actions?: IAction[];
connections?: IConnection[];
}
export type TBeforeRequest = {
($: IGlobalVariable, requestConfig: AxiosRequestConfig): AxiosRequestConfig;
} }
export interface IData { export interface IData {
@@ -243,7 +248,9 @@ export interface ISubstep {
} }
export type IHttpClientParams = { export type IHttpClientParams = {
$: IGlobalVariable;
baseURL?: string; baseURL?: string;
beforeRequest?: TBeforeRequest[];
}; };
export type IGlobalVariable = { export type IGlobalVariable = {
@@ -252,7 +259,7 @@ export type IGlobalVariable = {
data: IJSONObject; data: IJSONObject;
}; };
app: IApp; app: IApp;
http: IHttpClient; http?: IHttpClient;
flow?: { flow?: {
id: string; id: string;
lastInternalId: string; lastInternalId: string;

View File

@@ -31,12 +31,11 @@ type Response = {
export default function AddAppConnection(props: AddAppConnectionProps): React.ReactElement { export default function AddAppConnection(props: AddAppConnectionProps): React.ReactElement {
const { application, connectionId, onClose } = props; const { application, connectionId, onClose } = props;
const { name, authDocUrl, key, auth } = application; const { name, authDocUrl, key, auth } = application;
const { fields, authenticationSteps, reconnectionSteps } = auth;
const formatMessage = useFormatMessage(); const formatMessage = useFormatMessage();
const [errorMessage, setErrorMessage] = React.useState<string | null>(null); const [errorMessage, setErrorMessage] = React.useState<string | null>(null);
const [inProgress, setInProgress] = React.useState(false); const [inProgress, setInProgress] = React.useState(false);
const hasConnection = Boolean(connectionId); const hasConnection = Boolean(connectionId);
const steps = hasConnection ? reconnectionSteps : authenticationSteps; const steps = hasConnection ? auth?.reconnectionSteps : auth?.authenticationSteps;
React.useEffect(() => { React.useEffect(() => {
if (window.opener) { if (window.opener) {
@@ -46,6 +45,8 @@ export default function AddAppConnection(props: AddAppConnectionProps): React.Re
}, []); }, []);
const submitHandler: SubmitHandler<FieldValues> = React.useCallback(async (data) => { const submitHandler: SubmitHandler<FieldValues> = React.useCallback(async (data) => {
if (!steps) return;
setInProgress(true); setInProgress(true);
setErrorMessage(null); setErrorMessage(null);
@@ -106,7 +107,7 @@ export default function AddAppConnection(props: AddAppConnectionProps): React.Re
<DialogContent> <DialogContent>
<DialogContentText tabIndex={-1} component="div"> <DialogContentText tabIndex={-1} component="div">
<Form onSubmit={submitHandler}> <Form onSubmit={submitHandler}>
{fields?.map((field: IField) => (<InputCreator key={field.key} schema={field} />))} {auth?.fields?.map((field: IField) => (<InputCreator key={field.key} schema={field} />))}
<LoadingButton <LoadingButton
type="submit" type="submit"