Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
export const plugin: PluginFunction = (schema: GraphQLSchema, documents: Types.DocumentFile[], config: TypeScriptResolversPluginConfig) => {
const imports = [];
if (!config.customResolveInfo) {
imports.push('GraphQLResolveInfo');
}
const showUnusedMappers = typeof config.showUnusedMappers === 'boolean' ? config.showUnusedMappers : true;
const noSchemaStitching = typeof config.noSchemaStitching === 'boolean' ? config.noSchemaStitching : false;
if (config.noSchemaStitching === false) {
console['warn'](`The default behavior of 'noSchemaStitching' will be reversed in the next major release. Support for Schema Stitching will be disabled by default.`);
}
const indexSignature = config.useIndexSignature ? ['export type WithIndex = TObject & Record;', 'export type ResolversObject = WithIndex;'].join('\n') : '';
const transformedSchema = config.federation ? addFederationReferencesToSchema(schema) : schema;
const visitor = new TypeScriptResolversVisitor(config, transformedSchema);
const printedSchema = config.federation ? printSchemaWithDirectives(transformedSchema) : printSchema(transformedSchema);
const astNode = parse(printedSchema);
// runs visitor
const visitorResult = visit(astNode, { leave: visitor });
const defsToInclude = [];
const stitchingResolverType = `
export type StitchingResolver = {
fragment: string;
resolve: ResolverFn;
};
`;
const resolverType = `export type Resolver =`;
const resolverFnUsage = `ResolverFn`;
if (insideIgnoredFragment) {
return;
}
if (schema) {
const lastType = typesStack[typesStack.length - 1];
if (lastType && (isObjectType(lastType) || isInterfaceType(lastType))) {
const currentType = lastType.getFields()[node.name.value].type;
// To handle `Maybe` usage
if (hasNullableTypeRecursively(currentType)) {
foundFields++;
}
typesStack.push(getBaseType(currentType));
}
}
const selections = node.selectionSet ? node.selectionSet.selections || [] : [];
const relevantFragmentSpreads = selections.filter(s => s.kind === Kind.FRAGMENT_SPREAD && !externalFragments.includes(s.name.value));
if (selections.length === 0 || relevantFragmentSpreads.length > 0) {
foundFields++;
}
},
leave: (node: FieldNode, key, parent, path, anscestors) => {
async function normalize() {
/* Load Require extensions */
const requireExtensions = normalizeInstanceOrArray(config.require);
for (const mod of requireExtensions) {
await import(mod);
}
/* Root templates-config */
rootConfig = config.config || {};
/* Normalize root "schema" field */
rootSchemas = normalizeInstanceOrArray(config.schema);
/* Normalize root "documents" field */
rootDocuments = normalizeInstanceOrArray(config.documents);
/* Normalize "generators" field */
const generateKeys = Object.keys(config.generates);
async function normalize() {
/* Load Require extensions */
const requireExtensions = normalizeInstanceOrArray(config.require);
for (const mod of requireExtensions) {
await import(mod);
}
/* Root templates-config */
rootConfig = config.config || {};
/* Normalize root "schema" field */
rootSchemas = normalizeInstanceOrArray(config.schema);
/* Normalize root "documents" field */
rootDocuments = normalizeInstanceOrArray(config.documents);
/* Normalize "generators" field */
const generateKeys = Object.keys(config.generates);
if (generateKeys.length === 0) {
throw new DetailedError(
'Invalid Codegen Configuration!',
`
Please make sure that your codegen config file contains the "generates" field, with a specification for the plugins you need.
It should looks like that:
schema:
export const createWatcher = (initalContext: CodegenContext, onNext: (result: Types.FileOutput[]) => Promise) => {
debugLog(`[Watcher] Starting watcher...`);
let config: Types.Config = initalContext.getConfig();
const files: string[] = [initalContext.filepath].filter(a => a);
const documents = normalizeInstanceOrArray(config.documents);
const schemas = normalizeInstanceOrArray(config.schema);
// Add schemas and documents from "generates"
Object.keys(config.generates)
.map(filename => normalizeOutputParam(config.generates[filename]))
.forEach(conf => {
schemas.push(...normalizeInstanceOrArray(conf.schema));
documents.push(...normalizeInstanceOrArray(conf.documents));
});
if (documents) {
documents.forEach(doc => {
if (typeof doc === 'string') {
files.push(doc);
} else {
files.push(...Object.keys(doc));
}
export const createWatcher = (initalContext: CodegenContext, onNext: (result: Types.FileOutput[]) => Promise) => {
debugLog(`[Watcher] Starting watcher...`);
let config: Types.Config = initalContext.getConfig();
const files: string[] = [initalContext.filepath].filter(a => a);
const documents = normalizeInstanceOrArray(config.documents);
const schemas = normalizeInstanceOrArray(config.schema);
// Add schemas and documents from "generates"
Object.keys(config.generates)
.map(filename => normalizeOutputParam(config.generates[filename]))
.forEach(conf => {
schemas.push(...normalizeInstanceOrArray(conf.schema));
documents.push(...normalizeInstanceOrArray(conf.documents));
});
if (documents) {
documents.forEach(doc => {
if (typeof doc === 'string') {
files.push(doc);
} else {
files.push(...Object.keys(doc));
async function normalize() {
/* Load Require extensions */
const requireExtensions = normalizeInstanceOrArray(config.require);
for (const mod of requireExtensions) {
await import(mod);
}
/* Root templates-config */
rootConfig = config.config || {};
/* Normalize root "schema" field */
rootSchemas = normalizeInstanceOrArray(config.schema);
/* Normalize root "documents" field */
rootDocuments = normalizeInstanceOrArray(config.documents);
/* Normalize "generators" field */
const generateKeys = Object.keys(config.generates);
if (generateKeys.length === 0) {
throw new DetailedError(
'Invalid Codegen Configuration!',
`
Please make sure that your codegen config file contains the "generates" field, with a specification for the plugins you need.
It should looks like that:
schema:
- my-schema.graphql
generates:
my-file.ts:
if (!linkFieldNode) {
linkFieldNode = {
selectedFieldType: selectedField.type,
field: selectionNode,
};
linkFieldSelectionSets.set(fieldName, linkFieldNode);
} else {
mergeSelectionSets(linkFieldNode.field.selectionSet, selectionNode.selectionSet);
}
}
}
}
const linkFields: LinkField[] = [];
for (const { field, selectedFieldType } of linkFieldSelectionSets.values()) {
const realSelectedFieldType = getBaseType(selectedFieldType as any);
const selectionSet = this.createNext(realSelectedFieldType, field.selectionSet);
linkFields.push({
alias: field.alias ? field.alias.value : undefined,
name: field.name.value,
type: realSelectedFieldType.name,
selectionSet: this._processor.config.wrapTypeWithModifiers(
selectionSet
.transformSelectionSet()
.split(`\n`)
.join(`\n `),
selectedFieldType as any
),
});
}
export const plugin: PluginFunction = (schema: GraphQLSchema, documents: Types.DocumentFile[], config: FlowResolversPluginConfig) => {
const imports = ['type GraphQLResolveInfo'];
const showUnusedMappers = typeof config.showUnusedMappers === 'boolean' ? config.showUnusedMappers : true;
const gqlImports = `import { ${imports.join(', ')} } from 'graphql';`;
const transformedSchema = config.federation ? addFederationReferencesToSchema(schema) : schema;
const printedSchema = config.federation ? printSchemaWithDirectives(transformedSchema) : printSchema(transformedSchema);
const astNode = parse(printedSchema);
const visitor = new FlowResolversVisitor(config, transformedSchema);
const visitorResult = visit(astNode, { leave: visitor });
const defsToInclude: string[] = [visitor.getResolverTypeWrapperSignature()];
if (visitor.hasFederation()) {
defsToInclude.push(`
export type ReferenceResolver = (
reference: TReference,
context: TContext,
info: GraphQLResolveInfo
) => Promise | TResult;
`);
const childFields: ChildField[] = [...(options.additionalFields || [])];
const childInlineFragments: { onType: string; node: InlineFragmentNode }[] = [];
const childFragmentSpread: LoadedFragment[] = [...(options.additionalFragments || [])];
const selections = [...(options.selectionSet || [])];
const responseFieldArr: string[] = [];
for (const selection of selections) {
if (selection.kind === Kind.FIELD) {
this._imports.add(Imports.ResponseField);
const field = fields[selection.name.value];
const isObject = selection.selectionSet && selection.selectionSet.selections && selection.selectionSet.selections.length > 0;
const isNonNull = isNonNullType(field.type);
const fieldAnnotation = isNonNull ? 'Nonnull' : 'Nullable';
this._imports.add(Imports[fieldAnnotation]);
const baseType = getBaseType(field.type);
const isList = isListType(field.type) || (isNonNullType(field.type) && isListType(field.type.ofType));
if (isObject) {
let childClsName = this.convertName(field.name);
if (isList && isPlural(childClsName)) {
childClsName = singular(childClsName);
}
this.transformSelectionSet(
{
className: childClsName,
result: options.result,
selectionSet: selection.selectionSet.selections,
schemaType: baseType as GraphQLObjectType,
},