getFormFragments = ({
    formType = 'new', // new || edit
    collectionName,
    typeName,
    schema,
    fields, // restrict on certain fields
    addFields, // add additional fields (eg to display static fields)
}) => {

    // get the root schema fieldNames
    let queryFieldNames = getQueryFieldNames({ schema, options: { formType } });
    let mutationFieldNames = getMutationFieldNames({
        queryFieldNames,
        readableFieldNames: getFragmentFieldNames({ schema, options: { onlyViewable: true } })
    });

    // if "fields" prop is specified, restrict list of fields to it
    if (typeof fields !== 'undefined' && fields.length > 0) {
        // add "_intl" suffix to all fields in case some of them are intl fields
        const fieldsWithIntlSuffix = fields.map(field => `${field}${intlSuffix}`);
        const allFields = [...fields, ...fieldsWithIntlSuffix];
        queryFieldNames = _intersection(queryFieldNames, allFields);
        mutationFieldNames = _intersection(mutationFieldNames, allFields);
    }

    // add "addFields" prop contents to list of fields
    if (addFields && addFields.length) {
        queryFieldNames = queryFieldNames.concat(addFields);
        mutationFieldNames = mutationFieldNames.concat(addFields);
    }

    // userId is used to check for permissions, so add it to fragments if possible
    if (schema.userId) {
        queryFieldNames.unshift('userId');
        mutationFieldNames.unshift('userId');
    }

    if (schema._id) {
        queryFieldNames.unshift('_id');
        mutationFieldNames.unshift('_id');
    }

    // check unicity (_id can be added twice)
    queryFieldNames = _uniq(queryFieldNames);
    mutationFieldNames = _uniq(mutationFieldNames);


    // generate query fragment based on the fields that can be edited. Note: always add _id, and userId if possible.
    // TODO: support nesting
    const queryFragmentText = getSchemaFragment({
        schema,
        fragmentName: `fragment ${getFragmentName(formType, collectionName, 'query')} on ${typeName}`,
        options: { formType, isMutation: false },
        fieldNames: queryFieldNames
    });
    const generatedQueryFragment = gql(queryFragmentText);

    const mutationFragmentText = getSchemaFragment({
        schema,
        fragmentName: `fragment ${getFragmentName(formType, collectionName, 'mutation')} on ${typeName}`,
        options: { formType, isMutation: true },
        fieldNames: mutationFieldNames
    });
    // generate mutation fragment based on the fields that can be edited and/or viewed. Note: always add _id, and userId if possible.
    // TODO: support nesting
    const generatedMutationFragment = gql(mutationFragmentText);

    // if any field specifies extra queries, add them
    const extraQueries = _.compact(
        getQueryFieldNames({ schema, options: { formType } }).map(fieldName => {
            const field = schema[fieldName];
            return field.query;
        })
    );
    // get query & mutation fragments from props or else default to same as generatedFragment
    return {
        queryFragment: generatedQueryFragment,
        mutationFragment: generatedMutationFragment,
        extraQueries
    };
}
Generate query and mutation fragments for forms