@graphql-mesh/transform-snapshot
Version:
83 lines (77 loc) • 3.28 kB
JavaScript
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
const schema = require('@graphql-tools/schema');
const resolversComposition = require('@graphql-tools/resolvers-composition');
const crossHelpers = require('@graphql-mesh/cross-helpers');
const objectHash = _interopDefault(require('object-hash'));
const utils = require('@graphql-mesh/utils');
function computeSnapshotFilePath(options) {
const typeName = options.info.parentType.name;
const fieldName = options.info.fieldName;
const hashObj = options.respectSelectionSet
? {
args: options.args,
fieldNodes: options.info.fieldNodes,
}
: options.args;
const hash = objectHash(hashObj, { ignoreUnknown: true }).toString();
const fileName = [typeName, fieldName, hash].join('_') + '.json';
return crossHelpers.path.join(options.outputDir, fileName);
}
const writeSnapshotFile = async (path, json) => {
try {
await utils.writeJSON(path, json, null, 2);
}
catch (e) {
console.error(`Snapshot cannot saved to ${path}: ${e.message}`);
}
};
class SnapshotTransform {
constructor({ baseDir, config, importFn }) {
this.noWrap = true;
this.config = config;
this.baseDir = baseDir;
this.importFn = importFn;
}
transformSchema(schema$1) {
// TODO: Needs to be changed!
const configIf = 'if' in this.config
? typeof this.config.if === 'boolean'
? this.config.if
: // eslint-disable-next-line no-new-func
this.config.if && new Function(`return ${this.config.if}`)()
: true;
if (configIf) {
const resolvers = utils.extractResolvers(schema$1);
const resolversComposition$1 = {};
const outputDir = crossHelpers.path.isAbsolute(this.config.outputDir)
? this.config.outputDir
: crossHelpers.path.join(this.baseDir, this.config.outputDir);
const snapshotComposition = next => async (root, args, context, info) => {
const snapshotFilePath = computeSnapshotFilePath({
info,
args,
outputDir,
respectSelectionSet: this.config.respectSelectionSet,
});
if (snapshotFilePath in require.cache || (await utils.pathExists(snapshotFilePath))) {
return this.importFn(snapshotFilePath);
}
const result = await next(root, args, context, info);
await writeSnapshotFile(snapshotFilePath, result);
return result;
};
for (const field of this.config.apply) {
resolversComposition$1[field] = snapshotComposition;
}
const composedResolvers = resolversComposition.composeResolvers(resolvers, resolversComposition$1);
return schema.addResolversToSchema({
schema: schema$1,
resolvers: composedResolvers,
updateResolversInPlace: true,
});
}
return schema$1;
}
}
module.exports = SnapshotTransform;
;