insomnia/app/templating/base-extension.js

114 lines
2.8 KiB
JavaScript
Raw Normal View History

const EMPTY_ARG = '__EMPTY_NUNJUCKS_ARG__';
import * as models from '../models/index';
export default class BaseExtension {
constructor (ext) {
this._ext = ext;
this.tags = [this.getTag()];
}
getTag () {
return this._ext.name;
}
getPriority () {
return this._ext.priority || -1;
}
getName () {
return this._ext.displayName || this.getTag();
}
getDefaultFill () {
const args = this.getArgs().map(argDefinition => {
if (argDefinition.type === 'enum') {
const {defaultValue, options} = argDefinition;
const value = defaultValue !== undefined ? defaultValue : options[0].value;
return `'${value}'`;
} else if (argDefinition.type === 'number') {
const {defaultValue} = argDefinition;
return defaultValue !== undefined ? defaultValue : 0;
} else {
const {defaultValue} = argDefinition;
return defaultValue !== undefined ? `'${defaultValue}'` : "''";
}
});
return `${this.getTag()} ${args.join(', ')}`;
}
getDescription () {
return this._ext.description || 'no description';
}
getArgs () {
return this._ext.args || [];
}
isDeprecated () {
return this._ext.deprecated || false;
}
run (...args) {
return this._ext.run(...args);
}
parse (parser, nodes, lexer) {
const tok = parser.nextToken();
let args;
if (parser.peekToken().type !== lexer.TOKEN_BLOCK_END) {
args = parser.parseSignature(null, true);
} else {
// Not sure why this is needed, but it fails without it
args = new nodes.NodeList(tok.lineno, tok.colno);
args.addChild(new nodes.Literal(0, 0, EMPTY_ARG));
}
parser.advanceAfterBlockEnd(tok.value);
return new nodes.CallExtensionAsync(this, 'asyncRun', args);
}
asyncRun (...runArgs) {
// Pull the callback off the end
const callback = runArgs[runArgs.length - 1];
// Only pass render context, not the entire Nunjucks instance
const renderContext = runArgs[0].ctx;
// Extract the rest of the args
const args = runArgs
.slice(1, runArgs.length - 1)
.filter(a => a !== EMPTY_ARG);
// Define a plugin context with helpers
const pluginContext = {
context: renderContext,
models: {
request: {getById: models.request.getById},
response: {getLatestForRequestId: models.response.getLatestForRequest}
}
};
let result;
try {
result = this.run(pluginContext, ...args);
} catch (err) {
callback(err);
return;
}
// If the result is a promise, resolve it async
if (result instanceof Promise) {
result.then(
r => callback(null, r),
err => callback(err)
);
return;
}
// If the result is not a Promise, return it synchronously
callback(null, result);
}
}