Files
api/app/run.ts
Alexis Tyler 855ba2fc75 chore: lint
2021-01-29 12:03:26 +10:30

77 lines
1.8 KiB
TypeScript

import type { CoreContext, CoreResult, Result } from './core/types';
import { pubsub, coreLogger } from './core';
import { debugTimer, isNodeError } from './core/utils';
import { AppError } from './core/errors';
/**
* Publish update to topic channel.
*/
export const publish = async (channel: string, mutation: string, node?: Record<string, unknown>) => {
if (!node) {
throw new Error('Data missing?');
}
const data = {
[channel]: {
mutation,
node
}
};
// Update clients
const fieldName = Object.keys(data)[0];
await pubsub.publish(channel, {
[fieldName]: data[fieldName].node
});
};
interface RunOptions {
node?: Record<string, unknown>;
moduleToRun?: (context: CoreContext) => Promise<CoreResult | Result> | CoreResult | Result;
context?: any;
}
/**
* Run a module.
*/
export const run = async (channel: string, mutation: string, options: RunOptions) => {
const {
node,
moduleToRun,
context
} = options;
if (!moduleToRun) {
coreLogger.silly('Tried to run but has no "moduleToRun"');
await publish(channel, mutation, node);
return;
}
try {
// Run module
const result: CoreResult = await new Promise(resolve => {
debugTimer(`run:${moduleToRun.name}`);
resolve(moduleToRun(context));
});
// Log result
coreLogger.silly(`run:${moduleToRun.name}`, JSON.stringify(result.json));
// Save result
await publish(channel, mutation, result.json);
} catch (error: unknown) {
if (isNodeError(error, AppError)) {
// Ensure we aren't leaking anything in production
if (process.env.NODE_ENV === 'production') {
coreLogger.debug('Error:', error.message);
} else {
const logger = coreLogger[error.status && error.status >= 400 ? 'error' : 'warn'].bind(coreLogger);
logger('Error:', error.message);
}
}
}
debugTimer(`run:${moduleToRun.name}`);
};