Skip to content

Plugin API

By means of the plugin api it is possible to register hooks at important program points of httpYac.

ts
export interface HttpyacHooksApi{
  readonly version: string;
  readonly rootDir?: PathLike;
  readonly httpFile: Readonly<HttpFile>;
  readonly config: EnvironmentConfig;
  readonly hooks: HttpFileHooks;
  readonly log: LogHandler;
  readonly fileProvider: FileProvider,
  readonly sessionStore: SessionStore,
  readonly userInteractionProvider: UserInteractionProvider;
  getHookCancel(): symbol;
}
export interface HttpyacHooksApi{
  readonly version: string;
  readonly rootDir?: PathLike;
  readonly httpFile: Readonly<HttpFile>;
  readonly config: EnvironmentConfig;
  readonly hooks: HttpFileHooks;
  readonly log: LogHandler;
  readonly fileProvider: FileProvider,
  readonly sessionStore: SessionStore,
  readonly userInteractionProvider: UserInteractionProvider;
  getHookCancel(): symbol;
}

version

  • Type: string

The version string for the httpYac api version that is loading the plugin.

rootDir

  • Type: string

The project root directory of current http File.

httpFile

http file prepared for parsing, which has no regions yet.

config

Environment configuration determined for the current execution

log

The log module provides a simple debugging console. The output channel is redirected per use case

fileProvider

Data access layer for file access

WARNING

The VS Code extension also supports loading virtual documents. Direct access via fs is not always possible.

sessionStore

Service to store user sessions. The user has the possibility to delete them manually

userInteractionProvider

enables interaction with the user

getHookCancel

function to retrieve javascript symbol, which is used to cancel execution of hooks

hooks

List of hooks for which own program logic can be registered

ts
export interface HttpFileHooks{
  readonly parse: ParseHook,
  readonly parseEndRegion: ParseEndRegionHook,
  readonly replaceVariable: ReplaceVariableHook;
  readonly provideEnvironments: ProvideEnvironmentsHook;
  readonly provideVariables: ProvideVariablesHook;


  readonly onRequest: OnRequestHook;
  readonly onResponse: OnResponseHook,
  readonly responseLogging: ResponseLoggingHook,
}
export interface HttpFileHooks{
  readonly parse: ParseHook,
  readonly parseEndRegion: ParseEndRegionHook,
  readonly replaceVariable: ReplaceVariableHook;
  readonly provideEnvironments: ProvideEnvironmentsHook;
  readonly provideVariables: ProvideVariablesHook;


  readonly onRequest: OnRequestHook;
  readonly onResponse: OnResponseHook,
  readonly responseLogging: ResponseLoggingHook,
}

TIP

httpYac uses most of the hooks itself for its own application logic. Just look in the source code

ParseHook

hook for parsing http file. The goal is to determine and register the necessary actions for this line.

TIP

As soon as a hook determines a result, the processing for this row is aborted and the subsequent hooks are not processed (BailHook).

WARNING

Hook request and requestBody always returns a result. It is necessary to register your own parser before this one

js
module.exports = (api) => {
  api.hooks.parse.addHook('getCoffee', function (getLineReader, context) {
    const lineReader = getLineReader();
    let next = lineReader.next();
    if (!next.done) {
      // regex match if line is javascript start line
      const match = /^\s*GET\s+coffee?$/ui.test(next.value.textLine);
      if (!match) {
        return false;
      }

      context.httpRegion.hooks.execute.addHook('get_coffee', async context => {
        context.scriptConsole?.info?.(`get coffee`);
      });
      return { // return nextParserLine and symbol for lines
        nextParserLine: next.value.line,
        symbols: [{
          name: 'coffee',
          description: 'coffee with some milk, no sugar',
          kind: 'comment',
          startLine: next.value.line,
          startOffset: 0,
          endLine: next.value.line,
          endOffset: next.value.textLine.length,
        }]
      };
    }
    return false;
  }, {
    before: ['request']
  });
}
module.exports = (api) => {
  api.hooks.parse.addHook('getCoffee', function (getLineReader, context) {
    const lineReader = getLineReader();
    let next = lineReader.next();
    if (!next.done) {
      // regex match if line is javascript start line
      const match = /^\s*GET\s+coffee?$/ui.test(next.value.textLine);
      if (!match) {
        return false;
      }

      context.httpRegion.hooks.execute.addHook('get_coffee', async context => {
        context.scriptConsole?.info?.(`get coffee`);
      });
      return { // return nextParserLine and symbol for lines
        nextParserLine: next.value.line,
        symbols: [{
          name: 'coffee',
          description: 'coffee with some milk, no sugar',
          kind: 'comment',
          startLine: next.value.line,
          startOffset: 0,
          endLine: next.value.line,
          endOffset: next.value.textLine.length,
        }]
      };
    }
    return false;
  }, {
    before: ['request']
  });
}

full example

ParseEndRegionHook

  • Type: function

  • Arguments:

  • Return: void

hook after identifying new http region

ReplaceVariableHook

  • Type: function

  • Arguments:

  • Return: string

hook to replace variable in request line, header or request body

js
module.exports = (api) => {
  api.hooks.replaceVariable.addHook('changeXCoffeeHeader', async function (text, type) {
    if (type === 'X-Coffee') {
      return 'Black';
    }
    return text;
  });
}
module.exports = (api) => {
  api.hooks.replaceVariable.addHook('changeXCoffeeHeader', async function (text, type) {
    if (type === 'X-Coffee') {
      return 'Black';
    }
    return text;
  });
}

full example

ProvideVariablesHook

hook to provide custom variables

js
module.exports = (api) => {
  api.hooks.provideVariables.addHook('getCoffee', async function (envs) {
    if (envs && envs.length > 0) {
      return {
        system: envs[0],
        coffee: 'coffee with milk, no sugar',
      }
    }
    return {
      system: 'none',
      coffee: 'black',
    };
  });
  api.hooks.provideEnvironments.addHook('getCoffeeEnvironments', async function () {
    return ['kitchen', 'Riedbachstüberl'];
  });
}
module.exports = (api) => {
  api.hooks.provideVariables.addHook('getCoffee', async function (envs) {
    if (envs && envs.length > 0) {
      return {
        system: envs[0],
        coffee: 'coffee with milk, no sugar',
      }
    }
    return {
      system: 'none',
      coffee: 'black',
    };
  });
  api.hooks.provideEnvironments.addHook('getCoffeeEnvironments', async function () {
    return ['kitchen', 'Riedbachstüberl'];
  });
}

full example

ProvideEnvironmentsHook

  • Type: function

  • Arguments:

  • Return: Promise<string[]> list of possible environments

hook to provide environments

js
module.exports = (api) => {
  api.hooks.provideVariables.addHook('getCoffee', async function (envs) {
    if (envs && envs.length > 0) {
      return {
        system: envs[0],
        coffee: 'coffee with milk, no sugar',
      }
    }
    return {
      system: 'none',
      coffee: 'black',
    };
  });
  api.hooks.provideEnvironments.addHook('getCoffeeEnvironments', async function () {
    return ['kitchen', 'Riedbachstüberl'];
  });
}
module.exports = (api) => {
  api.hooks.provideVariables.addHook('getCoffee', async function (envs) {
    if (envs && envs.length > 0) {
      return {
        system: envs[0],
        coffee: 'coffee with milk, no sugar',
      }
    }
    return {
      system: 'none',
      coffee: 'black',
    };
  });
  api.hooks.provideEnvironments.addHook('getCoffeeEnvironments', async function () {
    return ['kitchen', 'Riedbachstüberl'];
  });
}

full example

OnRequest Hook

hook called before every request call

js
module.exports = (api) => {
  api.hooks.onRequest.addHook('getCoffee', function (request) {
    request.headers = Object.assign({
      'X-Coffee':  'coffee with milk, no sugar',
     }, request.headers);
  });
}
module.exports = (api) => {
  api.hooks.onRequest.addHook('getCoffee', function (request) {
    request.headers = Object.assign({
      'X-Coffee':  'coffee with milk, no sugar',
     }, request.headers);
  });
}

full example

OnResponse Hook

hook called after every response

js
module.exports = (api) => {
  api.hooks.onResponse.addHook('getCoffee', function (response) {
    response.body = 'coffee with milk, no sugar';
    delete response.parsedBody;
    delete response.prettyPrintBody;
  });
}
module.exports = (api) => {
  api.hooks.onResponse.addHook('getCoffee', function (response) {
    response.body = 'coffee with milk, no sugar';
    delete response.parsedBody;
    delete response.prettyPrintBody;
  });
}

full example

ResponseLoggingHook

hook called for every logging of a response.

js
module.exports = (api) => {
  api.hooks.responseLogging.addHook('removeHeadersAndRequest', async function (response) {
    delete response.headers;
    delete response.request;
    return response;
  });
}
module.exports = (api) => {
  api.hooks.responseLogging.addHook('removeHeadersAndRequest', async function (response) {
    delete response.headers;
    delete response.request;
    return response;
  });
}

full example