Skip to content

Commit

Permalink
feat: better server handling (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
AnWeber committed Feb 23, 2021
1 parent 91c302a commit 51ee3fa
Show file tree
Hide file tree
Showing 6 changed files with 498 additions and 163 deletions.
86 changes: 55 additions & 31 deletions src/actionProcessor/httpClientActionProcessor.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {ProcessorContext, HttpRequest, VariableReplacerType , HttpClientOptions, HttpFile, HttpRegion} from '../models';
import { isString, isMimeTypeFormUrlEncoded , isMimeTypeJSON, toEnvironmentKey , toConsoleOutput, decodeJWT} from '../utils';
import { httpYacApi } from '../httpYacApi';
import { log } from '../logger';
import { log, popupService } from '../logger';
import { isValidVariableName } from './jsActionProcessor';
import cloneDeep = require('lodash/cloneDeep');
import merge from 'lodash/merge';
Expand All @@ -11,27 +11,28 @@ const encodeUrl = require('encodeurl');

export async function httpClientActionProcessor(data: unknown, {httpRegion, httpFile, variables, progress, httpClient, showProgressBar}: ProcessorContext): Promise<boolean> {
if (httpRegion.request) {
const request = await replaceVariablesInRequest(httpRegion.request, {httpRegion, httpFile, variables, httpClient});
const options: HttpClientOptions = await initOptions(request, httpRegion.metaData.proxy);

try {
log.debug('request', options);

const response = await httpClient(options, progress, !!showProgressBar);
if (response) {
response.request = options;
httpRegion.response = response;
setResponseAsVariable(httpRegion, variables, httpFile);
log.info(toConsoleOutput(httpRegion.response));
} else {
return false;
const request = await replaceVariablesInRequest(httpRegion.request, { httpRegion, httpFile, variables, httpClient });
if (!!request) {
const options: HttpClientOptions = await initOptions(request, httpRegion.metaData.proxy);

try {
log.debug('request', options);

const response = await httpClient(options, progress, !!showProgressBar);
if (response) {
response.request = options;
httpRegion.response = response;
setResponseAsVariable(httpRegion, variables, httpFile);
log.info(toConsoleOutput(httpRegion.response));
return true;
}
} catch (err) {
log.error(httpRegion.request.url, options, err);
throw err;
}
} catch (err) {
log.error(httpRegion.request.url, options, err);
throw err;
}
}
return true;
return false;
};

function setResponseAsVariable(httpRegion: HttpRegion<any>, variables: Record<string, any>, httpFile: HttpFile) {
Expand All @@ -46,6 +47,7 @@ function setResponseAsVariable(httpRegion: HttpRegion<any>, variables: Record<st
handleNameMetaData(body, httpRegion, variables, httpFile);
}
} catch (err) {
popupService.warn('json parse error', body);
log.warn('json parse error', body, err);
}
}
Expand Down Expand Up @@ -88,18 +90,29 @@ async function normalizeBody(body: string | Array<string | (() => Promise<Buffer
async function replaceVariablesInRequest(request: HttpRequest, context: ProcessorContext) {
const replacedReqeust = cloneDeep(request);
context.request = replacedReqeust;
const replacer = (value: string, type: VariableReplacerType | string) => httpYacApi.replaceVariables(value, type, context);
replacedReqeust.url = await replacer(replacedReqeust.url, VariableReplacerType.url) || replacedReqeust.url;
for (const [headerName, headerValue] of Object.entries(replacedReqeust.headers)) {
if (isString(headerValue)) {
const value = await replacer(headerValue, headerName);
if (value === undefined) {
delete replacedReqeust.headers[headerName];
}else{
replacedReqeust.headers[headerName] = value;
}

let cancel = false;
context.cancelVariableReplacer = () => cancel = true;

const replacer = async (value: string, type: VariableReplacerType | string) => {
if (!cancel) {
return await httpYacApi.replaceVariables(value, type, context);
}
return value;
};

replacedReqeust.url = await replacer(replacedReqeust.url, VariableReplacerType.url) || replacedReqeust.url;
await replaceVariablesInHeader(replacedReqeust, replacer);
await replaceVariablesInBody(replacedReqeust, replacer);
delete context.request;
if (!cancel){
return replacedReqeust;
}
return false;
}


async function replaceVariablesInBody(replacedReqeust: HttpRequest<any>, replacer: (value: string, type: VariableReplacerType | string) => Promise<string | undefined>) {
if (replacedReqeust.body) {
if (isString(replacedReqeust.body)) {
replacedReqeust.body = await replacer(replacedReqeust.body, VariableReplacerType.body);
Expand All @@ -118,16 +131,27 @@ async function replaceVariablesInRequest(request: HttpRequest, context: Processo
replacedReqeust.body = replacedBody;
}
}
delete context.request;
return replacedReqeust;
}

async function replaceVariablesInHeader(replacedReqeust: HttpRequest<any>, replacer: (value: string, type: VariableReplacerType | string) => Promise<string | undefined>) {
for (const [headerName, headerValue] of Object.entries(replacedReqeust.headers)) {
if (isString(headerValue)) {
const value = await replacer(headerValue, headerName);
if (value === undefined) {
delete replacedReqeust.headers[headerName];
} else {
replacedReqeust.headers[headerName] = value;
}
}
}
}

function handleNameMetaData(body: unknown,httpRegion: HttpRegion<any>, variables: Record<string, any>, httpFile: HttpFile) {
if (httpRegion.metaData.name && isValidVariableName(httpRegion.metaData.name)) {
variables[httpRegion.metaData.name] = body;
httpFile.environments[toEnvironmentKey(httpFile.activeEnvironment)][httpRegion.metaData.name] = body;
} else if (httpRegion.metaData.name) {
popupService.warn(`Javascript Keyword ${httpRegion.metaData.name} not allowed as name`);
log.warn(`Javascript Keyword ${httpRegion.metaData.name} not allowed as name`);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/actionProcessor/intellijActionProcessor.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Variables, ProcessorContext, HttpRegion, HttpFile } from '../models';
import { ScriptData, executeScript } from './jsActionProcessor';
import { ok } from 'assert';
import { log } from '../logger';
import { log, popupService } from '../logger';
import { toAbsoluteFilename } from '../utils';
import { promises as fs } from 'fs';

Expand Down Expand Up @@ -38,6 +38,7 @@ async function loadScript(file: string, httpFile: HttpFile) {
}
return script;
} catch (err) {
popupService.error(`error loading script ${file}`);
log.warn(file, err);
return false;
}
Expand Down
70 changes: 60 additions & 10 deletions src/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,70 @@ export enum LogLevel{
}


export interface PopupService{
readonly info: (...data: Array<any>) => void;
readonly error: (...data:Array<any>) => void;
readonly warn: (...data:Array<any>) => void;

}

export interface Logger {
level: LogLevel,
info: (...data: Array<any>) => void;
trace: (...data:Array<any>) => void;
debug: (...data:Array<any>) => void;
error: (...data:Array<any>) => void;
warn: (...data:Array<any>) => void;
readonly info: (...data: Array<any>) => void;
readonly trace: (...data:Array<any>) => void;
readonly debug: (...data:Array<any>) => void;
readonly error: (...data:Array<any>) => void;
readonly warn: (...data:Array<any>) => void;
}


export type LogMethod = (level: LogLevel, ...params: any[]) => void;


function logToOutputChannel(level: LogLevel, logger: LogMethod, ...params: any[]) {
if (level >= log.level) {
logger(level, ...params);
}
}

export interface OutputProvider{
log: LogMethod,
showMessage?: LogMethod;
}

export const outputProvider: OutputProvider = {
log: (level, ...params) => {
switch (level) {
case LogLevel.trace:
console.trace(...params);
break;
case LogLevel.debug:
console.debug(...params);
break;
case LogLevel.error:
console.error(...params);
break;
case LogLevel.warn:
console.warn(...params);
break;
default:
console.info(...params);
break;
}
},
};

export const log: Logger = {
level: LogLevel.warn,
info: console.info,
trace: console.trace,
debug: console.debug,
error: console.error,
warn: console.warn,
info: (...params) => logToOutputChannel(LogLevel.info, outputProvider.log, ...params),
trace: (...params) => logToOutputChannel(LogLevel.trace, outputProvider.log, ...params),
debug: (...params) => logToOutputChannel(LogLevel.debug, outputProvider.log, ...params),
error: (...params) => logToOutputChannel(LogLevel.error, outputProvider.log, ...params),
warn: (...params) => logToOutputChannel(LogLevel.warn, outputProvider.log, ...params),
};

export const popupService: PopupService = {
info: (...params) => logToOutputChannel(LogLevel.info, outputProvider.showMessage || outputProvider.log, ...params),
error: (...params) => logToOutputChannel(LogLevel.error, outputProvider.showMessage || outputProvider.log, ...params),
warn: (...params) => logToOutputChannel(LogLevel.warn, outputProvider.showMessage || outputProvider.log, ...params),
};
1 change: 1 addition & 0 deletions src/models/processorContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ export interface HttpRegionSendContext extends HttpFileSendContext{
export interface ProcessorContext extends HttpRegionSendContext{
variables: Variables;
request?: HttpRequest;
cancelVariableReplacer?: () => void;
showProgressBar?: boolean;
}
Loading

0 comments on commit 51ee3fa

Please sign in to comment.