UNPKG

graphql-codegen-faker-fixtures

Version:

Generate faker fixtures for your fields

1 lines 23.4 kB
{"version":3,"sources":["../src/plugin.ts"],"sourcesContent":["import type {\n ASTNode,\n DocumentNode,\n EnumTypeDefinitionNode,\n InterfaceTypeDefinitionNode,\n ListTypeNode,\n NamedTypeNode,\n NonNullTypeNode,\n ObjectTypeDefinitionNode,\n SelectionSetNode,\n UnionTypeDefinitionNode,\n} from \"graphql\";\nimport { Kind, parse, printSchema, visit } from \"graphql\";\nimport {\n Enum,\n Field,\n Fragment,\n FragmentField,\n Union,\n Plugin,\n PluginConfig,\n} from \"./types\";\nimport { resolveExternalModuleAndFn } from \"@graphql-codegen/plugin-helpers\";\n\n// This plugin was generated with the help of ast explorer.\n// https://astexplorer.net\n// Paste your graphql schema in it, and you'll be able to see what the `astNode` will look like\n// The tool is awesome, you should check it out :-)\n// Pro-tip: play around with some TypeScript-code too!\n\nlet pluginConfig: PluginConfig;\n\n/**\n * The entry-point called from graphql-codegen\n *\n * This plugin works in three steps:\n *\n * 1. Collect all data-types on all fields defined in graphql Types/Interfaces\n * 2. Collect all fields defined in Fragments, and map them against the collected fields in step-1.\n * 3. Write typescript based on gathered info in step 2.\n *\n */\nexport const plugin: Plugin = (schema, documents, config) => {\n // -------------------------------------------\n // Make the plugin config easilty accessible througout the file.\n // -------------------------------------------\n pluginConfig = config;\n const { typeImport, skipFragments, buildersOnly, fakerjsSeed } = pluginConfig;\n\n // -------------------------------------------\n // We define some helpers and imports.\n // -------------------------------------------\n\n const disclaimer = `\n /* NOTE: This file is auto-generated. DO NOT EDIT. */\n `;\n\n const imports = [\n `import * as types from '${typeImport || \"CONFIGURE_TYPE_IMPORT\"}';`,\n `import { deepmergeCustom } from 'deepmerge-ts'`,\n `import { faker } from '@faker-js/faker';`,\n ].join(\"\\n\");\n\n const utils = `\n export type DeepPartial<T> = T extends object\n ? { [P in keyof T]?: DeepPartial<T[P]> }\n : T\n\n export const repeat = <T>(numTimes: number, callback: (i: number) => T) =>\n Array.from(Array(numTimes).keys()).map((i) => callback(i))\n\n const deepmerge = deepmergeCustom({ mergeArrays: false })\n export const merge = <T>(fixture: T, override: unknown) =>\n deepmerge(fixture, override) as T\n\n export const random = (min: number, max: number) => faker.number.int({ min, max })\n\n faker.seed(${fakerjsSeed || 12345654321})\n `;\n\n // Parse the schema into a `DocumentNode` we're able to parse.\n // The schema includes all Graphql-types but does NOT contain any fragments\n // Have a look at https://astexplorer.net to see what the DocumentNode looks like.\n const astSchema = parse(printSchema(schema));\n\n // Make an array of all given documents.\n // The documents contain all the fragments, but do NOT contain any graphql-types.\n const documentNodes = documents\n .map((document) => document.document)\n .filter(Boolean) as DocumentNode[];\n\n // Collect enums, fields, and unions from schema.\n // We use them to look up the types defined in the fragments.\n const { enums, fields, unions } = collectFromSchema(astSchema);\n\n // Collect all fragments (and its fields) in a flat-array.\n const fragments = documentNodes.flatMap((documentNode) =>\n collectFragments(documentNode, fields),\n );\n\n // Create all fragment-builders using the information we have collected earlier.\n const code = fragments\n .filter((fragment) => !skipFragments?.includes(fragment.fragmentName))\n .map((fragment) => createFragmentBuilder(fragment, enums, unions))\n .join(\"\\n\");\n\n // Combine all the things in a nice prettified file\n const parts = buildersOnly ? [code] : [disclaimer, imports, utils, code];\n return parts.join(\"\\n\\n\");\n};\n\n/**\n * Collect all fields, enums, unions from the Schema.\n * Note: the Schema does NOT contain any fragments.\n */\nconst collectFromSchema = (\n astNode: ASTNode,\n): { fields: Field[]; enums: Enum[]; unions: Union[] } => {\n // Setup arrays, we push everything we find along the way in them.\n const fields: Field[] = [];\n const enums: Enum[] = [];\n const unions: Union[] = [];\n\n // ObjectType and InterfaceTypes are so similar they can use the same visitFn\n const visitObjectTypeOrInterfaceType = (\n node: ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode,\n ) => {\n const objectName = node.name.value;\n\n node?.fields?.forEach((field) => {\n const fieldName = field.name.value;\n const fieldType = collectFieldType(field.type);\n\n const isArray =\n field.type.kind === Kind.NON_NULL_TYPE\n ? field.type.type.kind === Kind.LIST_TYPE\n : field.type.kind === Kind.LIST_TYPE;\n\n fields.push({\n objectName,\n fieldType,\n fieldName,\n isArray,\n });\n });\n };\n\n // Visit the astNode-tree using the visit-method provided by graphql-codegen\n visit(astNode, {\n EnumTypeDefinition: {\n leave: (node: EnumTypeDefinitionNode) => {\n const enumName = node.name.value;\n const enumValues = node?.values?.map((value) => value.name.value) || [];\n enums.push({ enumName, enumValues });\n },\n },\n // Gets called every time the visitor visits an UnionTypeDefinition\n UnionTypeDefinition: {\n leave: (node: UnionTypeDefinitionNode) => {\n const unionName = node.name.value;\n const unionValues =\n node.types?.map((namedTypeNode) => namedTypeNode.name.value) || [];\n\n unions.push({ unionName, unionValues });\n },\n },\n // Gets called every time the visitor visits an ObjectTypeDefinition\n ObjectTypeDefinition: {\n leave: visitObjectTypeOrInterfaceType,\n },\n // Gets called every time the visitor visits an InterfaceTypeDefinition\n InterfaceTypeDefinition: {\n leave: visitObjectTypeOrInterfaceType,\n },\n });\n\n return { fields, enums, unions };\n};\n\n/**\n * Collect the actual FieldType, as node could be wrapped with a NON_NULL_TYPE or LIST_TYPE (or both).\n * E.g: String!, [String], [String!], [String!]!\n *\n * We're only interested in the type being a string.\n */\nconst collectFieldType = (\n node: NonNullTypeNode | ListTypeNode | NamedTypeNode,\n): string => {\n if (node.kind === Kind.NON_NULL_TYPE || node.kind === Kind.LIST_TYPE) {\n // ...nope, not interesting yet. Let's dig deeper.\n return collectFieldType(node.type);\n }\n return node.name.value;\n};\n\n/**\n * Collect all Fragments from a document\n */\nconst collectFragments = (\n astNode: ASTNode,\n collectedFields: Field[],\n): Fragment[] => {\n const fragments: Fragment[] = [];\n\n const collectFieldsInFragment = (\n node: SelectionSetNode,\n objectName: string,\n ) => {\n const fields: FragmentField[] = [];\n\n node.selections.map((selection) => {\n if (selection.kind === Kind.FIELD) {\n // ... we have encountered a 'regular' field.\n const fieldName = selection.name.value;\n\n const collectedField: Field | undefined =\n fieldName === \"__typename\"\n ? // We have encountered a '__typename' field.\n // These are special as they should have a hardcoded value: objectName\n {\n fieldType: \"__typename\",\n fieldName: \"__typename\",\n objectName: objectName,\n }\n : // field was not a __typename.\n // Let's see if we can find the Field we have collected earlier.\n // It should contain more info on its type.\n collectedFields.find(\n (collectedField) =>\n collectedField.objectName === objectName &&\n collectedField.fieldName === fieldName,\n );\n\n if (!collectedField) {\n throw new Error(\n `Could not find type for field ${fieldName} in fragment for ${objectName}`,\n );\n }\n\n // Important: clone (!) collectedField into fragmentField.\n // We want to make sure this fragment does not 'mess' with fields for other fragments.\n let field: FragmentField = { ...collectedField };\n\n // Was field aliased in fragment?\n // If so: use the alias as fieldName in the builder.\n const fieldAlias = selection.alias?.value;\n if (fieldAlias) {\n field = { ...field, fieldName: fieldAlias };\n }\n\n // Field has subfields. Let's recursively find them.\n if (selection.selectionSet) {\n field = {\n ...field,\n fields: collectFieldsInFragment(\n selection.selectionSet,\n field.fieldType,\n ),\n };\n }\n\n fields.push(field);\n } else if (selection.kind === Kind.FRAGMENT_SPREAD) {\n // Have a look at `./tests/fragment_spread.test.ts` to see what a FRAGMENT_SPREAD is\n fields.push({\n spreadName: selection.name.value,\n isSpread: true,\n fieldName: \"\",\n fieldType: \"\",\n objectName: \"\",\n });\n } else if (selection.kind === Kind.INLINE_FRAGMENT) {\n // Have a look at `./tests/inline_fragment.test.ts` to see what a INLINE_FRAGMENT is\n const objectName = selection.typeCondition?.name.value || \"\";\n fields.push({\n fieldName: \"\",\n fieldType: \"\",\n objectName: objectName,\n isSpread: true,\n fields: collectFieldsInFragment(selection.selectionSet, objectName),\n });\n }\n });\n\n return fields;\n };\n\n visit(astNode, {\n FragmentDefinition: {\n leave: (node) => {\n const fragmentName = node.name.value;\n const objectName = node.typeCondition.name.value;\n const fields = collectFieldsInFragment(node.selectionSet, objectName);\n fragments.push({ fragmentName, objectName, fields });\n },\n },\n });\n\n return fragments;\n};\n\n/**\n * Creates a cased fragmentName based on the given `namingConvention`.\n * `change-case-all#pascalCase` by default.\n */\nconst convertToCorrectCaseType = (fragmentName: string): string => {\n const { namingConvention } = pluginConfig;\n\n if (!namingConvention) {\n return resolveExternalModuleAndFn(\"change-case-all#pascalCase\")(\n fragmentName,\n );\n }\n\n if (namingConvention === \"keep\") {\n return fragmentName;\n }\n\n return resolveExternalModuleAndFn(namingConvention)(fragmentName);\n};\n/**\n * Creates the actual fragment-factory\n */\nconst createFragmentBuilder = (\n fragment: Fragment,\n enums: Enum[],\n unions: Union[],\n) => {\n const name = fragment.fragmentName;\n const casedName = convertToCorrectCaseType(name);\n const typeName = `types.${casedName}Fragment`;\n const partialTypeName = `DeepPartial<${typeName}>`;\n\n const isUnion = unions.some(\n (union) => union.unionName === fragment.objectName,\n );\n\n if (isUnion) {\n return `\n export const fake${casedName} = ():${typeName} =>\n faker.helpers.arrayElement([\n ${fragment.fields\n .filter((field) => field.spreadName)\n .map((field) => convertToCorrectCaseType(field.spreadName || \"\"))\n .map((casedName) => `fake${casedName}()`)\n .join(\",\")}\n ])\n `;\n }\n\n return `\n export const fake${casedName} = (override?:${partialTypeName}):${typeName} => {\n const fixture:${typeName} = {\n ${createFakerFields(fragment.fields, enums, casedName)}\n }\n\n return override\n ? merge(fixture, override)\n : fixture\n }\n `;\n};\n\n/**\n * Creates the fields within a fixture object.\n */\nconst createFakerFields = (\n fields: FragmentField[],\n enums: Enum[],\n casedName: string,\n) => {\n const { skipFields } = pluginConfig;\n const shouldSkipField = (fieldName: string) =>\n skipFields?.includes(`${casedName}Fragment.${fieldName}`);\n\n // We deal with spreads and nonSpreads separately\n const nonSpreads = fields.filter((field) => !field.isSpread);\n const spreads = fields.filter((field) => field.isSpread);\n\n const nonSpreadString = nonSpreads\n .filter((field) => !shouldSkipField(field.fieldName))\n .map((field) => createFakerValue(field, enums, casedName))\n .join(\",\");\n\n const spreadValues = spreads\n .filter((field) => !shouldSkipField(field.fieldName))\n .map((field) => createFakerValue(field, enums, casedName));\n\n let spreadString: string = \"\";\n\n if (spreadValues.length === 1) {\n spreadString = `...${spreadValues[0]}`;\n } else if (spreadValues.length > 1) {\n spreadString = `...faker.helpers.arrayElement([${spreadValues.join(\",\")}])`;\n }\n\n return [nonSpreadString, spreadString].filter(Boolean).join(\",\");\n};\n\n/**\n * Creates a 'row' in the fixture object.\n */\nconst createFakerValue = (\n field: FragmentField,\n enums: Enum[],\n casedName: string,\n): string => {\n if (field.fieldName === \"__typename\") {\n return `__typename: '${field.objectName}'`;\n }\n\n const prefix = field.isArray ? \"repeat(random(1 , 5), () => (\" : \"\";\n const suffix = field.isArray ? \"))\" : \"\";\n\n if (field.spreadName) {\n // Field was a named spread:\n const fragmentName = convertToCorrectCaseType(field.spreadName);\n return `${prefix}fake${fragmentName}()${suffix}`;\n }\n\n if (field.fields && field.isSpread && !field.spreadName) {\n // Field was an inline-spread:\n // Recursively go back to createFakerFields to render its subfields:\n const subFields = createFakerFields(field.fields, enums, casedName);\n return `${prefix}{${subFields}}${suffix}`;\n }\n\n if (field.fields) {\n // Field has subfields:\n if (field.fields.length === 0) {\n throw new Error(\"Field should have subFields\");\n }\n\n // Recursively go back to createFakerFields to render the subfields:\n const subFields = createFakerFields(field.fields, enums, casedName);\n\n return `${field.fieldName}: ${prefix}{ ${subFields} }${suffix}`;\n }\n\n // Field was a Scalar field:\n const fakerMethod = createFakerMethod(field, enums);\n if (fakerMethod) {\n return `${field.fieldName}: ${prefix}${fakerMethod}${suffix}`;\n }\n\n return \"\";\n};\n\nconst findFakerMethodOfScalar = (\n scalar: string,\n defaultMethod: string,\n field: Field,\n) => {\n const { scalars } = pluginConfig;\n const scalarConfig = scalars?.[scalar];\n const defaultFieldMethod = scalars?.[scalar]?._default || defaultMethod;\n\n if (!scalarConfig) {\n return defaultFieldMethod;\n }\n\n if (`${field.objectName}.${field.fieldName}` in scalarConfig) {\n if (\n typeof scalarConfig[`${field.objectName}.${field.fieldName}`] !== \"string\"\n ) {\n throw Error(\n `Configuration error: value of ${field.objectName}.${field.fieldName} in ${scalar} is not of type \"string\".`,\n );\n }\n return scalarConfig[`${field.objectName}.${field.fieldName}`];\n }\n\n if (field.fieldName in scalarConfig) {\n if (typeof scalarConfig[field.fieldName] !== \"string\") {\n throw Error(\n `Configuration error: value of ${field.fieldName} in ${scalar} is not of type \"string\".`,\n );\n }\n return scalarConfig[field.fieldName];\n }\n\n return defaultFieldMethod;\n};\n\nconst findFieldAsExistingEnum = (field: Field, enums: Enum[]) => {\n return enums.find((myEnum) => myEnum.enumName === field.fieldType);\n};\n\nconst findDefaultFakerMethodForScalar = (scalar: string) => {\n switch (scalar) {\n case \"Int\":\n return \"faker.number.int()\";\n case \"Float\":\n return \"faker.number.float()\";\n case \"Boolean\":\n return \"faker.datatype.boolean()\";\n case \"ID\":\n return \"faker.string.uuid()\";\n case \"String\":\n default:\n return \"faker.lorem.words()\";\n }\n};\n\n// prettier-ignore\nconst createFakerMethod = (field: Field, enums: Enum[]) => {\n const myEnum = findFieldAsExistingEnum(field, enums)\n\n if (myEnum) {\n return `faker.helpers.arrayElement(${JSON.stringify(myEnum.enumValues)})`\n } else {\n return findFakerMethodOfScalar(field.fieldType, findDefaultFakerMethodForScalar(field.fieldType), field);\n }\n}\n"],"mappings":"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","names":["collectedField","objectName","casedName"]}