@graphql-mesh/transform-mock
Version:
150 lines (147 loc) • 8.6 kB
JavaScript
import { createMockStore, addMocksToSchema } from '@graphql-tools/mock';
import faker from 'faker';
import { loadFromModuleExportExpression } from '@graphql-mesh/utils';
import { mocks } from 'graphql-scalars';
import { getInterpolatedStringFactory } from '@graphql-mesh/string-interpolation';
import { process } from '@graphql-mesh/cross-helpers';
import { getResolversFromSchema } from '@graphql-tools/utils';
import { addResolversToSchema } from '@graphql-tools/schema';
class MockingTransform {
constructor({ baseDir, config, importFn }) {
this.noWrap = true;
this.config = config;
this.baseDir = baseDir;
this.importFn = importFn;
}
transformSchema(schema, context, transformedSchema) {
var _a, _b, _c, _d;
const configIf = this.config != null && 'if' in this.config ? this.config.if : true;
if (configIf) {
const mocks$1 = {
...mocks,
};
const resolvers = {};
const typeMap = schema.getTypeMap();
for (const typeName in typeMap) {
const type = typeMap[typeName];
const examples = type.extensions.examples;
if (examples === null || examples === void 0 ? void 0 : examples.length) {
mocks$1[typeName] = () => examples[Math.floor(Math.random() * examples.length)];
}
}
if ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.mocks) === null || _b === void 0 ? void 0 : _b.length) {
for (const fieldConfig of this.config.mocks) {
const fieldConfigIf = 'if' in fieldConfig ? fieldConfig.if : true;
if (fieldConfigIf) {
const [typeName, fieldName] = fieldConfig.apply.split('.');
if (fieldName) {
if (fieldConfig.faker) {
let fakerFn; // eslint-disable-line
const [service, method] = fieldConfig.faker.split('.');
if (service in faker) {
fakerFn = () => faker[service][method]();
}
else {
fakerFn = () => faker.fake(fieldConfig.faker || '');
}
resolvers[typeName] = resolvers[typeName] || {};
resolvers[typeName][fieldName] = fakerFn;
}
else if (fieldConfig.custom) {
const exportedVal$ = loadFromModuleExportExpression(fieldConfig.custom, {
cwd: this.baseDir,
defaultExportName: 'default',
importFn: this.importFn,
});
resolvers[typeName] = resolvers[typeName] || {};
resolvers[typeName][fieldName] = (root, args, context, info) => {
context = context || {};
context.mockStore = store;
return exportedVal$.then(exportedVal => typeof exportedVal === 'function' ? exportedVal(root, args, context, info) : exportedVal);
};
}
else if ('length' in fieldConfig) {
resolvers[typeName] = resolvers[typeName] || {};
resolvers[typeName][fieldName] = () => new Array(fieldConfig.length).fill({});
}
else if ('updateStore' in fieldConfig) {
const getFromStoreKeyFactory = getInterpolatedStringFactory(fieldConfig.store.key);
const updateStoreFactories = fieldConfig.updateStore.map(updateStoreConfig => ({
updateStoreConfig,
keyFactory: getInterpolatedStringFactory(updateStoreConfig.key),
valueFactory: getInterpolatedStringFactory(updateStoreConfig.value),
}));
resolvers[typeName] = resolvers[typeName] || {};
resolvers[typeName][fieldName] = (root, args, context, info) => {
const resolverData = { root, args, context, info, random: Date.now().toString(), env: process.env };
updateStoreFactories.forEach(({ updateStoreConfig, keyFactory, valueFactory }) => {
const key = keyFactory(resolverData);
const value = valueFactory(resolverData);
store.set(updateStoreConfig.type, key, updateStoreConfig.fieldName, value);
});
const key = getFromStoreKeyFactory(resolverData);
return store.get(fieldConfig.store.type, key, fieldConfig.store.fieldName);
};
}
else if ('store' in fieldConfig) {
const keyFactory = getInterpolatedStringFactory(fieldConfig.store.key);
resolvers[typeName] = resolvers[typeName] || {};
resolvers[typeName][fieldName] = (root, args, context, info) => {
const key = keyFactory({ root, args, context, info, env: process.env });
return store.get(fieldConfig.store.type, key, fieldConfig.store.fieldName);
};
}
}
else {
if (fieldConfig.faker) {
let fakerFn;
const [service, method] = fieldConfig.faker.split('.');
if (service in faker) {
fakerFn = () => faker[service][method]();
}
else {
fakerFn = () => faker.fake(fieldConfig.faker || '');
}
mocks$1[typeName] = fakerFn;
}
else if (fieldConfig.custom) {
const exportedVal$ = loadFromModuleExportExpression(fieldConfig.custom, {
cwd: this.baseDir,
defaultExportName: 'default',
importFn: this.importFn,
});
mocks$1[typeName] = () => {
return exportedVal$.then(exportedVal => typeof exportedVal === 'function' ? exportedVal(store) : exportedVal);
};
}
}
}
}
}
const store = createMockStore({ schema, mocks: mocks$1 });
if ((_c = this.config) === null || _c === void 0 ? void 0 : _c.initializeStore) {
const initializeStoreFn$ = loadFromModuleExportExpression(this.config.initializeStore, {
cwd: this.baseDir,
defaultExportName: 'default',
importFn: this.importFn,
});
// eslint-disable-next-line no-void
void initializeStoreFn$.then(fn => fn(store));
}
const newResolvers = getResolversFromSchema(addMocksToSchema({
schema: transformedSchema || schema,
store,
mocks: mocks$1,
resolvers,
preserveResolvers: (_d = this.config) === null || _d === void 0 ? void 0 : _d.preserveResolvers,
}), true);
addResolversToSchema({
schema: transformedSchema || schema,
resolvers: newResolvers,
updateResolversInPlace: true,
});
}
return schema;
}
}
export default MockingTransform;