2017-06-01 02:04:27 +00:00
|
|
|
import * as models from '../models/index';
|
2017-06-09 01:10:12 +00:00
|
|
|
import * as templating from './index';
|
2017-12-21 14:01:51 +00:00
|
|
|
import * as pluginContexts from '../plugins/context';
|
2021-05-12 06:35:00 +00:00
|
|
|
import { database as db } from '../common/database';
|
2019-05-08 17:36:55 +00:00
|
|
|
import { decodeEncoding } from './utils';
|
2021-05-12 06:35:00 +00:00
|
|
|
import { PluginTemplateTag } from './extensions';
|
2017-06-01 02:04:27 +00:00
|
|
|
|
2017-11-20 16:07:36 +00:00
|
|
|
const EMPTY_ARG = '__EMPTY_NUNJUCKS_ARG__';
|
|
|
|
|
2017-06-01 02:04:27 +00:00
|
|
|
export default class BaseExtension {
|
2021-05-12 06:35:00 +00:00
|
|
|
_ext: PluginTemplateTag | null = null;
|
|
|
|
_plugin: Plugin | null = null;
|
|
|
|
tags: Array<PluginTemplateTag['name']> | null = null;
|
|
|
|
|
|
|
|
constructor(ext: PluginTemplateTag, plugin: Plugin) {
|
2017-06-01 02:04:27 +00:00
|
|
|
this._ext = ext;
|
2018-06-09 03:22:39 +00:00
|
|
|
this._plugin = plugin;
|
2021-05-12 06:35:00 +00:00
|
|
|
const tag = this.getTag();
|
|
|
|
this.tags = [
|
|
|
|
...(tag === null ? [] : [tag]),
|
|
|
|
];
|
2017-06-01 02:04:27 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 17:42:50 +00:00
|
|
|
getTag() {
|
2021-05-12 06:35:00 +00:00
|
|
|
return this._ext?.name || null;
|
2017-06-01 02:04:27 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 17:42:50 +00:00
|
|
|
getPriority() {
|
2021-05-12 06:35:00 +00:00
|
|
|
return this._ext?.priority || -1;
|
2017-06-01 02:04:27 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 17:42:50 +00:00
|
|
|
getName() {
|
2021-05-12 06:35:00 +00:00
|
|
|
return this._ext?.displayName || this.getTag();
|
2017-06-01 02:04:27 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 17:42:50 +00:00
|
|
|
getDescription() {
|
2021-05-12 06:35:00 +00:00
|
|
|
return this._ext?.description || 'no description';
|
2017-06-01 02:04:27 +00:00
|
|
|
}
|
|
|
|
|
2020-03-11 22:15:15 +00:00
|
|
|
getLiveDisplayName() {
|
2020-05-14 22:54:07 +00:00
|
|
|
return (
|
2021-05-12 06:35:00 +00:00
|
|
|
// @ts-expect-error -- TSCONVERSION
|
|
|
|
this._ext?.liveDisplayName ||
|
|
|
|
function() {
|
2020-05-14 22:54:07 +00:00
|
|
|
return '';
|
|
|
|
}
|
|
|
|
);
|
2020-03-11 22:15:15 +00:00
|
|
|
}
|
|
|
|
|
2019-04-18 21:01:15 +00:00
|
|
|
getDisablePreview() {
|
2021-05-12 06:35:00 +00:00
|
|
|
return this._ext?.disablePreview || (() => false);
|
2019-04-18 21:01:15 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 17:42:50 +00:00
|
|
|
getArgs() {
|
2021-05-12 06:35:00 +00:00
|
|
|
return this._ext?.args || [];
|
2017-06-01 02:04:27 +00:00
|
|
|
}
|
|
|
|
|
2020-11-30 23:15:17 +00:00
|
|
|
getActions() {
|
2021-05-12 06:35:00 +00:00
|
|
|
return this._ext?.actions || [];
|
2020-11-30 23:15:17 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 17:42:50 +00:00
|
|
|
isDeprecated() {
|
2021-05-12 06:35:00 +00:00
|
|
|
return this._ext?.deprecated || false;
|
2017-06-01 02:04:27 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 17:42:50 +00:00
|
|
|
run(...args) {
|
2021-05-12 06:35:00 +00:00
|
|
|
// @ts-expect-error -- TSCONVERSION
|
|
|
|
return this._ext?.run(...args);
|
2017-06-01 02:04:27 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 17:42:50 +00:00
|
|
|
parse(parser, nodes, lexer) {
|
2017-06-01 02:04:27 +00:00
|
|
|
const tok = parser.nextToken();
|
|
|
|
let args;
|
2021-05-12 06:35:00 +00:00
|
|
|
|
2017-06-01 02:04:27 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2018-06-25 17:42:50 +00:00
|
|
|
asyncRun({ ctx: renderContext }, ...runArgs) {
|
2017-06-01 02:04:27 +00:00
|
|
|
// Pull the callback off the end
|
|
|
|
const callback = runArgs[runArgs.length - 1];
|
2017-07-11 01:05:54 +00:00
|
|
|
// Pull out the meta helper
|
2017-06-09 01:10:12 +00:00
|
|
|
const renderMeta = renderContext.getMeta ? renderContext.getMeta() : {};
|
2017-12-21 14:01:51 +00:00
|
|
|
// Pull out the purpose
|
2018-10-17 16:42:33 +00:00
|
|
|
const renderPurpose = renderContext.getPurpose ? renderContext.getPurpose() : null;
|
2019-04-27 04:34:15 +00:00
|
|
|
// Pull out the environment ID
|
|
|
|
const environmentId = renderContext.getEnvironmentId ? renderContext.getEnvironmentId() : 'n/a';
|
2017-06-01 02:04:27 +00:00
|
|
|
// Extract the rest of the args
|
2019-05-08 17:36:55 +00:00
|
|
|
const args = runArgs
|
|
|
|
.slice(0, runArgs.length - 1)
|
|
|
|
.filter(a => a !== EMPTY_ARG)
|
|
|
|
.map(decodeEncoding);
|
2017-06-09 01:10:12 +00:00
|
|
|
// Define a helper context with utils
|
|
|
|
const helperContext = {
|
2017-12-21 14:01:51 +00:00
|
|
|
...pluginContexts.app.init(renderPurpose),
|
2021-05-12 06:35:00 +00:00
|
|
|
// @ts-expect-error -- TSCONVERSION
|
2018-06-09 03:22:39 +00:00
|
|
|
...pluginContexts.store.init(this._plugin),
|
2019-04-27 04:34:15 +00:00
|
|
|
...pluginContexts.network.init(environmentId),
|
2017-06-01 02:04:27 +00:00
|
|
|
context: renderContext,
|
2017-06-09 01:10:12 +00:00
|
|
|
meta: renderMeta,
|
2019-04-27 04:34:15 +00:00
|
|
|
renderPurpose,
|
2017-06-09 01:10:12 +00:00
|
|
|
util: {
|
2021-05-12 06:35:00 +00:00
|
|
|
render: str =>
|
|
|
|
templating.render(str, {
|
|
|
|
context: renderContext,
|
|
|
|
}),
|
2017-06-09 01:10:12 +00:00
|
|
|
models: {
|
2018-06-26 21:26:44 +00:00
|
|
|
request: {
|
|
|
|
getById: models.request.getById,
|
|
|
|
getAncestors: async request => {
|
|
|
|
const ancestors = await db.withAncestors(request, [
|
|
|
|
models.requestGroup.type,
|
2018-12-12 17:36:11 +00:00
|
|
|
models.workspace.type,
|
2018-06-26 21:26:44 +00:00
|
|
|
]);
|
|
|
|
return ancestors.filter(doc => doc._id !== request._id);
|
2018-12-12 17:36:11 +00:00
|
|
|
},
|
2018-06-26 21:26:44 +00:00
|
|
|
},
|
2021-05-12 06:35:00 +00:00
|
|
|
workspace: {
|
|
|
|
getById: models.workspace.getById,
|
|
|
|
},
|
|
|
|
oAuth2Token: {
|
|
|
|
getByRequestId: models.oAuth2Token.getByParentId,
|
|
|
|
},
|
2017-11-20 16:07:36 +00:00
|
|
|
cookieJar: {
|
|
|
|
getOrCreateForWorkspace: workspace => {
|
|
|
|
return models.cookieJar.getOrCreateForParentId(workspace._id);
|
2018-12-12 17:36:11 +00:00
|
|
|
},
|
2017-11-20 16:07:36 +00:00
|
|
|
},
|
2017-06-30 03:30:22 +00:00
|
|
|
response: {
|
|
|
|
getLatestForRequestId: models.response.getLatestForRequest,
|
2018-12-12 17:36:11 +00:00
|
|
|
getBodyBuffer: models.response.getBodyBuffer,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2017-06-01 02:04:27 +00:00
|
|
|
};
|
|
|
|
let result;
|
2021-05-12 06:35:00 +00:00
|
|
|
|
2017-06-01 02:04:27 +00:00
|
|
|
try {
|
2017-06-09 01:10:12 +00:00
|
|
|
result = this.run(helperContext, ...args);
|
2017-06-01 02:04:27 +00:00
|
|
|
} catch (err) {
|
2018-03-30 14:25:35 +00:00
|
|
|
// Catch sync errors
|
2017-06-01 02:04:27 +00:00
|
|
|
callback(err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the result is a promise, resolve it async
|
|
|
|
if (result instanceof Promise) {
|
2018-07-09 14:53:11 +00:00
|
|
|
result
|
|
|
|
.then(r => {
|
2018-03-30 14:25:35 +00:00
|
|
|
callback(null, r);
|
2018-07-09 14:53:11 +00:00
|
|
|
})
|
|
|
|
.catch(err => {
|
2018-03-30 14:25:35 +00:00
|
|
|
callback(err);
|
2018-07-09 14:53:11 +00:00
|
|
|
});
|
2017-06-01 02:04:27 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the result is not a Promise, return it synchronously
|
|
|
|
callback(null, result);
|
|
|
|
}
|
|
|
|
}
|